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: [],