diff --git a/frontend/src/component/application/ConnectedInstances/ConnectedInstances.tsx b/frontend/src/component/application/ConnectedInstances/ConnectedInstances.tsx
index b3b05592e1..f04bfe07cb 100644
--- a/frontend/src/component/application/ConnectedInstances/ConnectedInstances.tsx
+++ b/frontend/src/component/application/ConnectedInstances/ConnectedInstances.tsx
@@ -4,39 +4,125 @@ import { formatDateYMDHMS } from 'utils/formatDate';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { useConnectedInstancesTable } from './useConnectedInstancesTable';
import { ConnectedInstancesTable } from './ConnectedInstancesTable';
+import { IApplication } from 'interfaces/application';
+import { useQueryParam } from 'use-query-params';
+import { styled } from '@mui/material';
+
+const Container = styled('div')(({ theme }) => ({
+ '* + *': {
+ marginBlockStart: theme.spacing(2),
+ },
+}));
+
+const EnvironmentSelectionContainer = styled('div')(({ theme }) => ({
+ label: {
+ color: theme.palette.primary.main,
+ background: theme.palette.background,
+ paddingInline: theme.spacing(2),
+ paddingBlock: theme.spacing(1),
+ border: `1px solid ${theme.palette.background.alternative}`,
+ borderInlineStart: 'none',
+ fontWeight: 'bold',
+ },
+ 'label:first-of-type': {
+ borderInlineStart: `1px solid ${theme.palette.background.alternative}`,
+ borderRadius: `${theme.shape.borderRadiusMedium}px 0 0 ${theme.shape.borderRadiusMedium}px`,
+ },
+ 'label:last-of-type': {
+ borderRadius: `0 ${theme.shape.borderRadiusMedium}px ${theme.shape.borderRadiusMedium}px 0`,
+ },
+ 'label:has(input:checked)': {
+ background: theme.palette.background.alternative,
+ color: theme.palette.primary.contrastText,
+ },
+ 'label:focus-within': {
+ outline: `2px solid ${theme.palette.background.alternative}`,
+ outlineOffset: theme.spacing(0.5),
+ },
+
+ input: {
+ border: 0,
+ clip: 'rect(0 0 0 0)',
+ height: 'auto',
+ margin: 0,
+ overflow: 'hidden',
+ padding: 0,
+ position: 'absolute',
+ width: '1px',
+ whiteSpace: 'nowrap',
+ },
+}));
export const ConnectedInstances = () => {
const name = useRequiredPathParam('name');
const { application } = useApplication(name);
+ const [currentEnvironment, setCurrentEnvironment] =
+ useQueryParam('environment');
+ const availableEnvironments = new Set(
+ application?.instances.map(
+ // @ts-expect-error: the type definition here is incomplete. It
+ // should be updated as part of this project.
+ (instance) => instance.environment,
+ ),
+ );
+ const allEnvironmentsSorted = Array.from(availableEnvironments).sort(
+ (a, b) => a.localeCompare(b),
+ );
const tableData = useMemo(() => {
- return (
- application.instances
+ const map = ({
+ instanceId,
+ sdkVersion,
+ clientIp,
+ lastSeen,
+ }: IApplication['instances'][number]) => ({
+ instanceId,
+ ip: clientIp,
+ sdkVersion,
+ lastSeen: formatDateYMDHMS(lastSeen),
+ });
+ if (!currentEnvironment) {
+ return application.instances.map(map);
+ }
+ return application.instances
+ .filter(
// @ts-expect-error: the type definition here is incomplete. It
// should be updated as part of this project.
- .filter((instance) => instance.environment === 'production')
- .map(({ instanceId, sdkVersion, clientIp, lastSeen }) => {
- return {
- instanceId,
- ip: clientIp,
- sdkVersion,
- lastSeen: formatDateYMDHMS(lastSeen),
- };
- })
- );
- }, [application]);
+ (instance) => instance.environment === currentEnvironment,
+ )
+ .map(map);
+ }, [application, currentEnvironment]);
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } =
useConnectedInstancesTable(tableData);
return (
-
+
+
+ {allEnvironmentsSorted.map((env) => {
+ return (
+
+ );
+ })}
+
+
+
);
};
diff --git a/frontend/src/hooks/api/getters/useApplication/useApplication.ts b/frontend/src/hooks/api/getters/useApplication/useApplication.ts
index b8bc0e43df..0dd933ac37 100644
--- a/frontend/src/hooks/api/getters/useApplication/useApplication.ts
+++ b/frontend/src/hooks/api/getters/useApplication/useApplication.ts
@@ -47,7 +47,7 @@ const useApplication = (
appName: name,
color: '',
createdAt: '2022-02-02T21:04:00.268Z',
- descriotion: '',
+ description: '',
instances: [],
strategies: [],
seenToggles: [],