Skip to content

Commit

Permalink
Add deregistration button and modal to hosts list view
Browse files Browse the repository at this point in the history
  • Loading branch information
arbulu89 committed Jul 6, 2023
1 parent 9f4d1d9 commit 7acda32
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 2 deletions.
37 changes: 35 additions & 2 deletions assets/js/components/HostsList.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React from 'react';
import React, { useState } from 'react';

import { useSearchParams } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import { EOS_WARNING_OUTLINED } from 'eos-icons-react';

import Table from '@components/Table';
import DeregistrationModal from '@components/DeregistrationModal';
import HealthIcon from '@components/Health/HealthIcon';
import Tags from '@components/Tags';
import HostLink from '@components/HostLink';
Expand All @@ -16,8 +17,10 @@ import HealthSummary from '@components/HealthSummary/HealthSummary';
import { getCounters } from '@components/HealthSummary/summarySelection';
import ProviderLabel from '@components/ProviderLabel';
import Tooltip from '@components/Tooltip';
import CleanUpButton from '@components/CleanUpButton';

Check failure on line 20 in assets/js/components/HostsList.jsx

View workflow job for this annotation

GitHub Actions / Static Code Analysis

Unable to resolve path to module '@components/CleanUpButton'

import { addTagToHost, removeTagFromHost, deregisterHost } from '@state/hosts';

import { addTagToHost, removeTagFromHost } from '@state/hosts';
import { post, del } from '@lib/network';
import { agentVersionWarning } from '@lib/agent';

Expand Down Expand Up @@ -50,6 +53,8 @@ function HostsList() {
);

const [searchParams, setSearchParams] = useSearchParams();
const [cleanUpModalOpen, setCleanUpModalOpen] = useState(false);
const [selectedHost, setSelectedHost] = useState(undefined);

const dispatch = useDispatch();

Expand Down Expand Up @@ -177,6 +182,21 @@ function HostsList() {
/>
),
},
{
title: '',
key: 'deregisterable',
className: 'w-48',
render: (content, item) =>
content ? (
<CleanUpButton
cleaning={item.deregistering}
onClick={() => {
setSelectedHost(item);
setCleanUpModalOpen(true);
}}
/>
) : null,
},
],
};

Expand All @@ -199,13 +219,26 @@ function HostsList() {
id: host.id,
tags: (host.tags && host.tags.map((tag) => tag.value)) || [],
sap_systems: sapSystemList,
deregisterable: host.deregisterable,
deregistering: host.deregistering,
};
});

const counters = getCounters(data || []);
return (
<>
<PageHeader className="font-bold">Hosts</PageHeader>
<DeregistrationModal
hostname={selectedHost?.hostname}
isOpen={!!cleanUpModalOpen}
onCleanUp={() => {
setCleanUpModalOpen(false);
dispatch(deregisterHost(selectedHost));
}}
onCancel={() => {
setCleanUpModalOpen(false);
}}
/>
<div className="bg-white rounded-lg shadow">
<HealthSummary {...counters} className="px-4 py-2" />
<Table
Expand Down
91 changes: 91 additions & 0 deletions assets/js/components/HostsList.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,97 @@ describe('HostsLists component', () => {
});
});

describe('deregistration', () => {
it('should show the clean up button when the host is deregisterable', () => {
const host1 = hostFactory.build({ deregisterable: true });
const host2 = hostFactory.build({ deregisterable: false });
const state = {
...defaultInitialState,
hostsList: {
hosts: [].concat(host1, host2),
},
};

const [StatefulHostsList] = withState(<HostsList />, state);

renderWithRouter(StatefulHostsList);
const table = screen.getByRole('table');
const cleanUpCell1 = table.querySelector(
'tr:nth-child(1) > td:nth-child(9)'
);
const cleanUpCell2 = table.querySelector(
'tr:nth-child(1) > td:nth-child(9)'
);
expect(cleanUpCell1).toHaveTextContent('Clean up');
expect(cleanUpCell2).toHaveTextContent('Clean up');
});

it('should show the host in deregistering state', () => {
const host = hostFactory.build({
deregisterable: true,
deregistering: true,
});
const state = {
...defaultInitialState,
hostsList: {
hosts: [host],
},
};

const [StatefulHostsList] = withState(<HostsList />, state);

renderWithRouter(StatefulHostsList);
expect(screen.getByLabelText('Loading')).toBeInTheDocument();
});

it('should request a deregistration when the clean up button in the modal is clicked', async () => {
const user = userEvent.setup();

const host = hostFactory.build({ deregisterable: true });
const state = {
...defaultInitialState,
hostsList: {
hosts: [host],
},
};

const [StatefulHostsList, store] = withState(<HostsList />, state);

renderWithRouter(StatefulHostsList);

const table = screen.getByRole('table');
const cleanUpButton = table.querySelector(
'tr:nth-child(1) > td:nth-child(9) > button'
);

await user.click(cleanUpButton);

expect(
screen.getByText(
`Clean up data discovered by agent on host ${host.hostname}`
)
).toBeInTheDocument();

const cleanUpModalButton = screen.getAllByRole('button', {
name: 'Clean up',
})[1];

await user.click(cleanUpModalButton);

const actions = store.getActions();
const expectedActions = [
{
type: 'DEREGISTER_HOST',
payload: expect.objectContaining({
id: host.id,
hostname: host.hostname,
}),
},
];
expect(actions).toEqual(expect.arrayContaining(expectedActions));
});
});

describe('filtering', () => {
const cleanInitialState = {
hostsList: {
Expand Down

0 comments on commit 7acda32

Please sign in to comment.