Feat UI host transfer delete warnings (#26287)
For #25656 changed the copy for the delete and transfer host modal to be more clear about the disk encryption key behaviour **delete host modal**  **Transfer host modal**  If some of the following don't apply, delete the relevant line. <!-- Note that API documentation changes are now addressed by the product design team. --> - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. - [x ] Added/updated automated tests - [x] Manual QA for all new/changed functionality
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
- changed the copy for the delete and transfer host modal to be more clear about the disk encryption
|
||||
key behavior
|
||||
@@ -0,0 +1,64 @@
|
||||
import React from "react";
|
||||
import { noop } from "lodash";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
|
||||
import DeleteHostModal from "./DeleteHostModal";
|
||||
|
||||
describe("DeleteHostModal", () => {
|
||||
it("renders the number of hosts selected", () => {
|
||||
render(
|
||||
<DeleteHostModal
|
||||
selectedHostIds={[1, 2, 3]}
|
||||
onSubmit={noop}
|
||||
onCancel={noop}
|
||||
isUpdating={false}
|
||||
/>
|
||||
);
|
||||
expect(screen.getByText("3 hosts")).toBeVisible();
|
||||
});
|
||||
|
||||
it("renders the host name when only the host name is provided", () => {
|
||||
render(
|
||||
<DeleteHostModal
|
||||
hostName="Host1"
|
||||
onSubmit={noop}
|
||||
onCancel={noop}
|
||||
isUpdating={false}
|
||||
/>
|
||||
);
|
||||
expect(screen.getByText("Host1")).toBeVisible();
|
||||
});
|
||||
|
||||
it("renders the number of hosts selected with '+' after when select all matching hosts is true", () => {
|
||||
render(
|
||||
<DeleteHostModal
|
||||
selectedHostIds={[1, 2, 3]}
|
||||
hostsCount={50}
|
||||
isAllMatchingHostsSelected
|
||||
onSubmit={noop}
|
||||
onCancel={noop}
|
||||
isUpdating={false}
|
||||
/>
|
||||
);
|
||||
expect(screen.getByText("3+ hosts")).toBeVisible();
|
||||
});
|
||||
|
||||
it("renders the host count with '+' and an additional warning when there are more than 500 hosts and select all matching hosts is true", () => {
|
||||
render(
|
||||
<DeleteHostModal
|
||||
selectedHostIds={[1, 2, 3]}
|
||||
hostsCount={500}
|
||||
isAllMatchingHostsSelected
|
||||
onSubmit={noop}
|
||||
onCancel={noop}
|
||||
isUpdating={false}
|
||||
/>
|
||||
);
|
||||
expect(screen.getByText("3+ hosts")).toBeVisible();
|
||||
expect(
|
||||
screen.getByText(
|
||||
"When deleting a large volume of hosts, it may take some time for this change to be reflected in the UI."
|
||||
)
|
||||
).toBeVisible();
|
||||
});
|
||||
});
|
||||
@@ -47,25 +47,26 @@ const DeleteHostModal = ({
|
||||
}
|
||||
return hostName;
|
||||
};
|
||||
const largeVolumeText = (): string => {
|
||||
if (
|
||||
selectedHostIds &&
|
||||
isAllMatchingHostsSelected &&
|
||||
hostsCount &&
|
||||
hostsCount >= 500
|
||||
) {
|
||||
return " When deleting a large volume of hosts, it may take some time for this change to be reflected in the UI.";
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
const hasManyHosts =
|
||||
selectedHostIds &&
|
||||
isAllMatchingHostsSelected &&
|
||||
hostsCount &&
|
||||
hostsCount >= 500;
|
||||
|
||||
return (
|
||||
<Modal title="Delete host" onExit={onCancel} className={baseClass}>
|
||||
<>
|
||||
<p>
|
||||
This will remove the record of <b>{hostText()}</b> and associated data
|
||||
(e.g. unlock PINs).{largeVolumeText()}
|
||||
such as unlock PINs and disk encryption keys.
|
||||
</p>
|
||||
{hasManyHosts && (
|
||||
<p>
|
||||
When deleting a large volume of hosts, it may take some time for
|
||||
this change to be reflected in the UI.
|
||||
</p>
|
||||
)}
|
||||
<ul>
|
||||
<li>
|
||||
macOS, Windows, or Linux hosts will re-appear unless Fleet's
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import React from "react";
|
||||
import { noop } from "lodash";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
|
||||
import TransferHostModal from "./TransferHostModal";
|
||||
|
||||
describe("TransferHostModal", () => {
|
||||
it("renders the correct message when more than one host is being transfered", () => {
|
||||
render(
|
||||
<TransferHostModal
|
||||
multipleHosts
|
||||
teams={[]}
|
||||
onSubmit={noop}
|
||||
onCancel={noop}
|
||||
isUpdating={false}
|
||||
isGlobalAdmin={false}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByText(
|
||||
"The hosts' disk encryption keys are deleted if they're transferred to a team with disk encryption turned off."
|
||||
)
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
it("render the correct message when one host is being transfered", () => {
|
||||
render(
|
||||
<TransferHostModal
|
||||
multipleHosts={false}
|
||||
teams={[]}
|
||||
onSubmit={noop}
|
||||
onCancel={noop}
|
||||
isUpdating={false}
|
||||
isGlobalAdmin={false}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByText(
|
||||
"The host's disk encryption key is deleted if it's transferred to a team with disk encryption turned off."
|
||||
)
|
||||
).toBeVisible();
|
||||
});
|
||||
});
|
||||
@@ -65,43 +65,58 @@ const TransferHostModal = ({
|
||||
return [NO_TEAM_OPTION, ...teamOptions];
|
||||
};
|
||||
|
||||
const diskEncryptionMsg = (
|
||||
<>
|
||||
The {multipleHosts ? "hosts'" : "host's"} disk encryption{" "}
|
||||
{multipleHosts ? "keys are" : "key is"} deleted if{" "}
|
||||
{multipleHosts ? "they're" : "it's"} transferred to a team with disk
|
||||
encryption turned off.
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<Modal onExit={onCancel} title="Transfer hosts" className={baseClass}>
|
||||
<form className={`${baseClass}__form`}>
|
||||
<Dropdown
|
||||
wrapperClassName={`${baseClass}__team-dropdown-wrapper`}
|
||||
label={`Transfer ${multipleHosts ? "selected hosts" : "host"} to:`}
|
||||
value={selectedTeam && selectedTeam.id}
|
||||
options={createTeamDropdownOptions()}
|
||||
onChange={onChangeSelectTeam}
|
||||
placeholder="Select a team"
|
||||
searchable={false}
|
||||
autoFocus
|
||||
/>
|
||||
{isGlobalAdmin ? (
|
||||
<p>
|
||||
Team not here?{" "}
|
||||
<Link to={PATHS.ADMIN_TEAMS} className={`${baseClass}__team-link`}>
|
||||
Create a team
|
||||
</Link>
|
||||
</p>
|
||||
) : null}
|
||||
<div className="modal-cta-wrap">
|
||||
<Button
|
||||
disabled={selectedTeam === undefined}
|
||||
type="button"
|
||||
variant="brand"
|
||||
onClick={onSubmitTransferHost}
|
||||
className="transfer-loading"
|
||||
isLoading={isUpdating}
|
||||
>
|
||||
Transfer
|
||||
</Button>
|
||||
<Button onClick={onCancel} variant="inverse">
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
<>
|
||||
<p>{diskEncryptionMsg}</p>
|
||||
<form className={`${baseClass}__form`}>
|
||||
<Dropdown
|
||||
wrapperClassName={`${baseClass}__team-dropdown-wrapper`}
|
||||
label={`Transfer ${multipleHosts ? "selected hosts" : "host"} to:`}
|
||||
value={selectedTeam && selectedTeam.id}
|
||||
options={createTeamDropdownOptions()}
|
||||
onChange={onChangeSelectTeam}
|
||||
placeholder="Select a team"
|
||||
searchable={false}
|
||||
autoFocus
|
||||
/>
|
||||
{isGlobalAdmin ? (
|
||||
<p>
|
||||
Team not here?{" "}
|
||||
<Link
|
||||
to={PATHS.ADMIN_TEAMS}
|
||||
className={`${baseClass}__team-link`}
|
||||
>
|
||||
Create a team
|
||||
</Link>
|
||||
</p>
|
||||
) : null}
|
||||
<div className="modal-cta-wrap">
|
||||
<Button
|
||||
disabled={selectedTeam === undefined}
|
||||
type="button"
|
||||
variant="brand"
|
||||
onClick={onSubmitTransferHost}
|
||||
className="transfer-loading"
|
||||
isLoading={isUpdating}
|
||||
>
|
||||
Transfer
|
||||
</Button>
|
||||
<Button onClick={onCancel} variant="inverse">
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user