mirror of
https://github.com/Unleash/unleash.git
synced 2025-06-27 01:19:00 +02:00
refactor: connected instances extract hook refactoring (#6353)
This commit is contained in:
parent
d6e0bea2f0
commit
e9603f866b
@ -0,0 +1,95 @@
|
|||||||
|
import { screen } from '@testing-library/react';
|
||||||
|
import { render } from 'utils/testRenderer';
|
||||||
|
import { testServerRoute, testServerSetup } from 'utils/testServer';
|
||||||
|
import { Route, Routes } from 'react-router-dom';
|
||||||
|
import { ConnectedInstances } from './ConnectedInstances';
|
||||||
|
import { ApplicationEnvironmentInstancesSchemaInstancesItem } from '../../../openapi';
|
||||||
|
|
||||||
|
const server = testServerSetup();
|
||||||
|
|
||||||
|
const setupApi = (
|
||||||
|
instances: ApplicationEnvironmentInstancesSchemaInstancesItem[],
|
||||||
|
) => {
|
||||||
|
testServerRoute(server, '/api/admin/metrics/applications/my-app/overview', {
|
||||||
|
environments: [{ name: 'development' }, { name: 'production' }],
|
||||||
|
});
|
||||||
|
testServerRoute(server, '/api/admin/ui-config', {});
|
||||||
|
testServerRoute(server, '/api/admin/metrics/instances/my-app/development', {
|
||||||
|
instances,
|
||||||
|
});
|
||||||
|
testServerRoute(server, '/api/admin/metrics/instances/my-app/production', {
|
||||||
|
instances: [
|
||||||
|
{
|
||||||
|
instanceId: 'shouldNotShowUp',
|
||||||
|
clientIp: 'irrelevant',
|
||||||
|
lastSeen: '2024-02-26T14:00:59.980Z',
|
||||||
|
sdkVersion: 'irrelevant',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
test('Display connected instances', async () => {
|
||||||
|
setupApi([
|
||||||
|
{
|
||||||
|
instanceId: 'devInstance1',
|
||||||
|
clientIp: '192.168.0.1',
|
||||||
|
lastSeen: '2024-02-26T15:00:59.980Z',
|
||||||
|
sdkVersion: 'unleash-client-node:5.5.0',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
instanceId: 'devInstance2',
|
||||||
|
clientIp: '192.168.0.2',
|
||||||
|
lastSeen: '2024-02-26T14:00:59.980Z',
|
||||||
|
sdkVersion: 'unleash-client-node:5.5.1',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
render(
|
||||||
|
<Routes>
|
||||||
|
<Route
|
||||||
|
path={'/applications/:name/instances'}
|
||||||
|
element={<ConnectedInstances />}
|
||||||
|
/>
|
||||||
|
</Routes>,
|
||||||
|
{
|
||||||
|
route: '/applications/my-app/instances',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
await screen.findByText('development');
|
||||||
|
await screen.findByText('production');
|
||||||
|
await screen.findByText('devInstance1');
|
||||||
|
await screen.findByText('devInstance2');
|
||||||
|
await screen.findByText('192.168.0.1');
|
||||||
|
await screen.findByText('192.168.0.2');
|
||||||
|
await screen.findByText('unleash-client-node:5.5.0');
|
||||||
|
await screen.findByText('unleash-client-node:5.5.1');
|
||||||
|
|
||||||
|
expect(screen.queryByText('prodInstance')).not.toBeInTheDocument();
|
||||||
|
|
||||||
|
// check order
|
||||||
|
const [, row1, row2] = screen.getAllByRole('row');
|
||||||
|
expect(row1.textContent?.includes('devInstance1')).toBe(true);
|
||||||
|
expect(row2.textContent?.includes('devInstance2')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Display no connected instances', async () => {
|
||||||
|
setupApi([]);
|
||||||
|
render(
|
||||||
|
<Routes>
|
||||||
|
<Route
|
||||||
|
path={'/applications/:name/instances'}
|
||||||
|
element={<ConnectedInstances />}
|
||||||
|
/>
|
||||||
|
</Routes>,
|
||||||
|
{
|
||||||
|
route: '/applications/my-app/instances',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
await screen.findByText('development');
|
||||||
|
await screen.findByText('production');
|
||||||
|
await screen.findByText(
|
||||||
|
"There's no data for any connected instances to display. Have you configured your clients correctly?",
|
||||||
|
);
|
||||||
|
});
|
@ -7,30 +7,41 @@ import { Box, ToggleButton, ToggleButtonGroup } from '@mui/material';
|
|||||||
import { useApplicationOverview } from 'hooks/api/getters/useApplicationOverview/useApplicationOverview';
|
import { useApplicationOverview } from 'hooks/api/getters/useApplicationOverview/useApplicationOverview';
|
||||||
import { useConnectedInstances } from 'hooks/api/getters/useConnectedInstances/useConnectedInstances';
|
import { useConnectedInstances } from 'hooks/api/getters/useConnectedInstances/useConnectedInstances';
|
||||||
import { ApplicationEnvironmentInstancesSchemaInstancesItem } from '../../../openapi';
|
import { ApplicationEnvironmentInstancesSchemaInstancesItem } from '../../../openapi';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
|
||||||
export const ConnectedInstances: FC = () => {
|
const useEnvironments = (application: string) => {
|
||||||
const name = useRequiredPathParam('name');
|
const { data: applicationOverview } = useApplicationOverview(application);
|
||||||
const { data: applicationOverview } = useApplicationOverview(name);
|
|
||||||
|
const applicationEnvironments = applicationOverview.environments
|
||||||
|
.map((env) => env.name)
|
||||||
|
.sort();
|
||||||
|
|
||||||
const availableEnvironments = applicationOverview.environments.map(
|
|
||||||
(env) => env.name,
|
|
||||||
);
|
|
||||||
const allEnvironmentsSorted = Array.from(availableEnvironments).sort(
|
|
||||||
(a, b) => a.localeCompare(b),
|
|
||||||
);
|
|
||||||
const [currentEnvironment, setCurrentEnvironment] = useState(
|
const [currentEnvironment, setCurrentEnvironment] = useState(
|
||||||
allEnvironmentsSorted[0],
|
applicationEnvironments[0],
|
||||||
);
|
|
||||||
const { data: connectedInstances } = useConnectedInstances(
|
|
||||||
name,
|
|
||||||
currentEnvironment,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!currentEnvironment && availableEnvironments.length > 0) {
|
if (!currentEnvironment && applicationEnvironments.length > 0) {
|
||||||
setCurrentEnvironment(availableEnvironments[0]);
|
setCurrentEnvironment(applicationEnvironments[0]);
|
||||||
}
|
}
|
||||||
}, [JSON.stringify(availableEnvironments)]);
|
}, [JSON.stringify(applicationEnvironments)]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
currentEnvironment,
|
||||||
|
setCurrentEnvironment,
|
||||||
|
environments: applicationEnvironments,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ConnectedInstances: FC = () => {
|
||||||
|
const name = useRequiredPathParam('name');
|
||||||
|
const { currentEnvironment, setCurrentEnvironment, environments } =
|
||||||
|
useEnvironments(name);
|
||||||
|
|
||||||
|
const { data: connectedInstances, loading } = useConnectedInstances(
|
||||||
|
name,
|
||||||
|
currentEnvironment,
|
||||||
|
);
|
||||||
|
|
||||||
const tableData = useMemo(() => {
|
const tableData = useMemo(() => {
|
||||||
const map = ({
|
const map = ({
|
||||||
@ -61,6 +72,9 @@ export const ConnectedInstances: FC = () => {
|
|||||||
environments that have received traffic for this application
|
environments that have received traffic for this application
|
||||||
will be shown here.
|
will be shown here.
|
||||||
</Box>
|
</Box>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={Boolean(currentEnvironment)}
|
||||||
|
show={
|
||||||
<ToggleButtonGroup
|
<ToggleButtonGroup
|
||||||
color='primary'
|
color='primary'
|
||||||
value={currentEnvironment}
|
value={currentEnvironment}
|
||||||
@ -71,13 +85,19 @@ export const ConnectedInstances: FC = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{allEnvironmentsSorted.map((env) => {
|
{environments.map((env) => {
|
||||||
return <ToggleButton value={env}>{env}</ToggleButton>;
|
return (
|
||||||
|
<ToggleButton key={env} value={env}>
|
||||||
|
{env}
|
||||||
|
</ToggleButton>
|
||||||
|
);
|
||||||
})}
|
})}
|
||||||
</ToggleButtonGroup>
|
</ToggleButtonGroup>
|
||||||
|
}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<ConnectedInstancesTable
|
<ConnectedInstancesTable
|
||||||
loading={false}
|
loading={loading}
|
||||||
headerGroups={headerGroups}
|
headerGroups={headerGroups}
|
||||||
prepareRow={prepareRow}
|
prepareRow={prepareRow}
|
||||||
getTableBodyProps={getTableBodyProps}
|
getTableBodyProps={getTableBodyProps}
|
||||||
|
Loading…
Reference in New Issue
Block a user