diff --git a/frontend/src/component/application/ApplicationChart.tsx b/frontend/src/component/application/ApplicationChart.tsx
index 10707a664f..56a8e2bd0e 100644
--- a/frontend/src/component/application/ApplicationChart.tsx
+++ b/frontend/src/component/application/ApplicationChart.tsx
@@ -16,6 +16,7 @@ import WarningAmberRounded from '@mui/icons-material/WarningAmberRounded';
import { TimeAgo } from 'component/common/TimeAgo/TimeAgo';
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
import { getApplicationIssues } from './ApplicationIssues/ApplicationIssues';
+import { useUiFlag } from 'hooks/useUiFlag';
const StyledTable = styled('table')(({ theme }) => ({
fontSize: theme.fontSizes.smallerBody,
@@ -196,6 +197,7 @@ export const ApplicationChart = ({ data }: IApplicationChartProps) => {
const { elementRef, width } = useElementWidth();
const navigate = useNavigate();
const theme = useTheme();
+ const registerFrontendClientEnabled = useUiFlag('registerFrontendClient');
const mode = getApplicationIssues(data);
@@ -294,14 +296,57 @@ export const ApplicationChart = ({ data }: IApplicationChartProps) => {
{environment.instanceCount}
-
- SDK:
-
- {environment.sdks.map((sdk) => (
- {sdk}
- ))}
-
-
+ {!registerFrontendClientEnabled ? (
+
+ SDK:
+
+ {environment.sdks.map(
+ (sdk) => (
+
+ {sdk}
+
+ ),
+ )}
+
+
+ ) : null}
+
+ {registerFrontendClientEnabled &&
+ environment.backendSdks.length > 0 ? (
+
+
+ Backend SDK:
+
+
+ {environment.backendSdks.map(
+ (sdk) => (
+
+ {sdk}
+
+ ),
+ )}
+
+
+ ) : null}
+
+ {registerFrontendClientEnabled &&
+ environment.frontendSdks.length > 0 ? (
+
+
+ Frontend SDK:
+
+
+ {environment.frontendSdks.map(
+ (sdk) => (
+
+ {sdk}
+
+ ),
+ )}
+
+
+ ) : null}
+
Last seen:
diff --git a/frontend/src/component/application/ApplicationIssues/ApplicationIssues.test.tsx b/frontend/src/component/application/ApplicationIssues/ApplicationIssues.test.tsx
index d34dd14aef..d52daafd58 100644
--- a/frontend/src/component/application/ApplicationIssues/ApplicationIssues.test.tsx
+++ b/frontend/src/component/application/ApplicationIssues/ApplicationIssues.test.tsx
@@ -14,6 +14,8 @@ test('Display all application issues', async () => {
outdatedSdks: ['unleash-client-php:1.13.0'],
},
sdks: [],
+ backendSdks: [],
+ frontendSdks: [],
instanceCount: 0,
lastSeen: new Date().toISOString(),
name: 'development',
@@ -49,6 +51,8 @@ test('Each SDK version should be displayed once', async () => {
outdatedSdks: ['unleash-client-php:1.13.0'],
},
sdks: [],
+ frontendSdks: [],
+ backendSdks: [],
instanceCount: 0,
lastSeen: new Date().toISOString(),
name: 'development',
@@ -59,6 +63,8 @@ test('Each SDK version should be displayed once', async () => {
outdatedSdks: ['unleash-client-php:1.13.0'],
},
sdks: [],
+ frontendSdks: [],
+ backendSdks: [],
instanceCount: 0,
lastSeen: new Date().toISOString(),
name: 'production',
diff --git a/frontend/src/component/application/ApplicationOverview.test.tsx b/frontend/src/component/application/ApplicationOverview.test.tsx
index 284a95f582..a172f12898 100644
--- a/frontend/src/component/application/ApplicationOverview.test.tsx
+++ b/frontend/src/component/application/ApplicationOverview.test.tsx
@@ -26,6 +26,8 @@ test('Display application overview with environments', async () => {
instanceCount: 999,
lastSeen: new Date().toISOString(),
sdks: ['unleash-client-node:5.5.0-beta.0'],
+ frontendSdks: [],
+ backendSdks: ['unleash-client-node:5.5.0-beta.0'],
issues: {
missingFeatures: [],
outdatedSdks: [],
@@ -88,6 +90,8 @@ test('Display application with issues', async () => {
instanceCount: 999,
lastSeen: new Date().toISOString(),
sdks: ['unleash-client-node:5.5.0-beta.0'],
+ frontendSdks: [],
+ backendSdks: ['unleash-client-node:5.5.0-beta.0'],
issues: {
missingFeatures: ['feature1'],
outdatedSdks: [],
diff --git a/frontend/src/interfaces/uiConfig.ts b/frontend/src/interfaces/uiConfig.ts
index 2f72b543ad..8219614d11 100644
--- a/frontend/src/interfaces/uiConfig.ts
+++ b/frontend/src/interfaces/uiConfig.ts
@@ -96,6 +96,7 @@ export type UiFlags = {
newStrategyDropdown?: boolean;
flagsReleaseManagementUI?: boolean;
cleanupReminder?: boolean;
+ registerFrontendClient?: boolean;
};
export interface IVersionInfo {
diff --git a/frontend/src/openapi/models/applicationOverviewEnvironmentSchema.ts b/frontend/src/openapi/models/applicationOverviewEnvironmentSchema.ts
index f4aaef83e7..a5e6a0ca0b 100644
--- a/frontend/src/openapi/models/applicationOverviewEnvironmentSchema.ts
+++ b/frontend/src/openapi/models/applicationOverviewEnvironmentSchema.ts
@@ -22,4 +22,6 @@ export interface ApplicationOverviewEnvironmentSchema {
name: string;
/** SDKs used in the application environment */
sdks: string[];
+ backendSdks: string[];
+ frontendSdks: string[];
}
diff --git a/src/lib/db/client-applications-store.ts b/src/lib/db/client-applications-store.ts
index cdd35b36b2..e6c7d8b922 100644
--- a/src/lib/db/client-applications-store.ts
+++ b/src/lib/db/client-applications-store.ts
@@ -328,6 +328,12 @@ export default class ClientApplicationsStore
'ARRAY_AGG(DISTINCT ci.sdk_version) FILTER (WHERE ci.sdk_version IS NOT NULL) as sdk_versions',
),
this.db.raw('MAX(ci.last_seen) as latest_last_seen'),
+ this.db.raw(
+ "ARRAY_AGG(DISTINCT ci.sdk_version) FILTER (WHERE ci.sdk_type = 'frontend' AND ci.sdk_version IS NOT NULL) as frontend_sdks",
+ ),
+ this.db.raw(
+ "ARRAY_AGG(DISTINCT ci.sdk_version) FILTER (WHERE ci.sdk_type = 'backend' AND ci.sdk_version IS NOT NULL) as backend_sdks",
+ ),
])
.from('client_instances as ci')
.where('ci.app_name', appName)
@@ -340,6 +346,8 @@ export default class ClientApplicationsStore
'm.features',
'i.unique_instance_count',
'i.sdk_versions',
+ 'i.backend_sdks',
+ 'i.frontend_sdks',
'i.latest_last_seen',
'ca.strategies',
])
@@ -371,6 +379,8 @@ export default class ClientApplicationsStore
environment,
unique_instance_count,
sdk_versions,
+ frontend_sdks,
+ backend_sdks,
latest_last_seen,
project,
features,
@@ -396,6 +406,8 @@ export default class ClientApplicationsStore
name: environment,
instanceCount: Number(unique_instance_count),
sdks: sdk_versions || [],
+ frontendSdks: frontend_sdks || [],
+ backendSdks: backend_sdks || [],
lastSeen: latest_last_seen,
issues: {
missingFeatures: featuresNotMappedToProject
diff --git a/src/lib/features/metrics/instance/instance-service.test.ts b/src/lib/features/metrics/instance/instance-service.test.ts
index 5c79419807..469ed5f4e2 100644
--- a/src/lib/features/metrics/instance/instance-service.test.ts
+++ b/src/lib/features/metrics/instance/instance-service.test.ts
@@ -202,6 +202,8 @@ test('filter out private projects from overview', async () => {
name: 'development',
instanceCount: 1,
sdks: ['unleash-client-node:3.5.1'],
+ backendSdks: ['unleash-client-node:3.5.1'],
+ frontendSdks: [],
lastSeen: new Date(),
issues: {
missingFeatures: [],
diff --git a/src/lib/openapi/spec/application-overview-environment-schema.ts b/src/lib/openapi/spec/application-overview-environment-schema.ts
index 66fbd26348..d8f8cd3d35 100644
--- a/src/lib/openapi/spec/application-overview-environment-schema.ts
+++ b/src/lib/openapi/spec/application-overview-environment-schema.ts
@@ -6,7 +6,15 @@ export const applicationOverviewEnvironmentSchema = {
type: 'object',
description: 'Data about an application environment',
additionalProperties: false,
- required: ['name', 'instanceCount', 'sdks', 'lastSeen', 'issues'],
+ required: [
+ 'name',
+ 'instanceCount',
+ 'sdks',
+ 'frontendSdks',
+ 'backendSdks',
+ 'lastSeen',
+ 'issues',
+ ],
properties: {
name: {
description: 'Name of the application environment',
@@ -27,6 +35,22 @@ export const applicationOverviewEnvironmentSchema = {
},
example: ['unleash-client-node:5.4.0', 'unleash-client-node:5.3.0'],
},
+ frontendSdks: {
+ description: 'Frontend SDKs used in the application environment',
+ type: 'array',
+ items: {
+ type: 'string',
+ },
+ example: ['unleash-client-js:3.7.5'],
+ },
+ backendSdks: {
+ description: 'Backend SDKs used in the application environment',
+ type: 'array',
+ items: {
+ type: 'string',
+ },
+ example: ['unleash-client-node:5.4.0'],
+ },
lastSeen: {
type: 'string',
nullable: true,
diff --git a/src/lib/openapi/spec/application-overview-schema.test.ts b/src/lib/openapi/spec/application-overview-schema.test.ts
index c3483b3d4c..335252de1d 100644
--- a/src/lib/openapi/spec/application-overview-schema.test.ts
+++ b/src/lib/openapi/spec/application-overview-schema.test.ts
@@ -12,6 +12,8 @@ test('applicationOverviewSchema', () => {
name: 'production',
instanceCount: 34,
sdks: ['unleash-client-node:5.4.0'],
+ backendSdks: ['unleash-client-node:5.4.0'],
+ frontendSdks: [],
lastSeen: '2021-10-01T12:00:00Z',
issues: {
missingFeatures: ['feature1'],
@@ -22,6 +24,8 @@ test('applicationOverviewSchema', () => {
name: 'development',
instanceCount: 16,
sdks: ['unleash-client-java:5.4.0'],
+ backendSdks: ['unleash-client-java:5.4.0'],
+ frontendSdks: [],
lastSeen: '2021-10-01T12:00:00Z',
issues: {
missingFeatures: [],
diff --git a/src/test/e2e/api/admin/applications.e2e.test.ts b/src/test/e2e/api/admin/applications.e2e.test.ts
index 4e484489b3..b1b191fa19 100644
--- a/src/test/e2e/api/admin/applications.e2e.test.ts
+++ b/src/test/e2e/api/admin/applications.e2e.test.ts
@@ -128,6 +128,11 @@ test('should show correct application metrics', async () => {
{
instanceCount: 2,
name: 'default',
+ frontendSdks: [],
+ backendSdks: [
+ 'unleash-client-node:3.2.1',
+ 'unleash-client-node:3.2.2',
+ ],
sdks: [
'unleash-client-node:3.2.1',
'unleash-client-node:3.2.2',