-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
29f20c2
commit a698680
Showing
19 changed files
with
421 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { generateMAASURL, generateName } from "../../utils"; | ||
|
||
context("Settings - DHCP Snippets", () => { | ||
beforeEach(() => { | ||
cy.login(); | ||
cy.addMachine(); | ||
cy.visit(generateMAASURL("/settings/dhcp/add")); | ||
}); | ||
|
||
it("can add a DHCP snippet to a machine", () => { | ||
const snippetName = generateName("dhcp-snippet"); | ||
cy.get("[data-testid='section-header-title']").contains("Settings"); | ||
cy.findByLabelText("Snippet name").type(snippetName); | ||
cy.findByLabelText("Type").select("Machine"); | ||
cy.findByRole("button", { name: /Choose machine/ }).click(); | ||
// ensure the data has loaded | ||
cy.findByRole("grid").should("have.attr", "aria-busy", "false"); | ||
cy.get("tbody").within(() => { | ||
cy.findAllByRole("row").first().click(); | ||
}); | ||
cy.findByLabelText("DHCP snippet").type("ddns-update-style none;"); | ||
cy.findByRole("button", { name: "Save snippet" }).click(); | ||
// expect to be redirected to the list page | ||
cy.findByLabelText("Search DHCP snippets").type(snippetName); | ||
cy.findByRole("grid").within(() => { | ||
cy.findByText(snippetName).should("be.visible"); | ||
cy.findByRole("button", { name: /Delete/ }).click(); | ||
cy.get("[data-testid='action-confirm']").click(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
src/app/base/components/DhcpFormFields/MachineSelect/MachineSelect.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { screen } from "@testing-library/react"; | ||
import userEvent from "@testing-library/user-event"; | ||
|
||
import MachineSelect, { Labels } from "./MachineSelect"; | ||
|
||
import { renderWithMockStore } from "testing/utils"; | ||
|
||
it("can open select box on click", async () => { | ||
renderWithMockStore(<MachineSelect onSelect={jest.fn()} />); | ||
|
||
expect(screen.queryByRole("listbox")).not.toBeInTheDocument(); | ||
await userEvent.click( | ||
screen.getByRole("button", { name: Labels.ChooseMachine }) | ||
); | ||
expect(screen.getByRole("listbox")).toBeInTheDocument(); | ||
}); | ||
|
||
it("sets focus on the input field on open", async () => { | ||
renderWithMockStore(<MachineSelect onSelect={jest.fn()} />); | ||
|
||
await userEvent.click( | ||
screen.getByRole("button", { name: Labels.ChooseMachine }) | ||
); | ||
expect( | ||
screen.getByPlaceholderText("Search by hostname, system ID or tags") | ||
).toHaveFocus(); | ||
}); |
67 changes: 67 additions & 0 deletions
67
src/app/base/components/DhcpFormFields/MachineSelect/MachineSelect.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { useEffect, useState } from "react"; | ||
|
||
import { Label, useId } from "@canonical/react-components"; | ||
import { useDispatch } from "react-redux"; | ||
|
||
import SelectButton from "../../SelectButton"; | ||
|
||
import MachineSelectBox from "./MachineSelectBox"; | ||
|
||
import type { Machine } from "app/store/machine/types"; | ||
import { useFetchMachine } from "app/store/machine/utils/hooks"; | ||
import { actions as tagActions } from "app/store/tag"; | ||
|
||
export enum Labels { | ||
AppliesTo = "Applies to", | ||
Loading = "Loading...", | ||
ChooseMachine = "Choose machine", | ||
} | ||
|
||
type Props = { | ||
label?: string; | ||
onSelect: (machine: Machine | null) => void; | ||
selected?: Machine["system_id"] | null; | ||
}; | ||
|
||
export const MachineSelect = ({ | ||
label = Labels.AppliesTo, | ||
onSelect, | ||
selected = null, | ||
}: Props): JSX.Element => { | ||
const dispatch = useDispatch(); | ||
const [isOpen, setIsOpen] = useState(false); | ||
const selectId = useId(); | ||
const handleSelect = (machine: Machine | null) => { | ||
setIsOpen(false); | ||
onSelect(machine); | ||
}; | ||
|
||
const { machine: selectedMachine } = useFetchMachine(selected, { | ||
keepPreviousData: true, | ||
}); | ||
|
||
useEffect(() => { | ||
dispatch(tagActions.fetch()); | ||
}, [dispatch]); | ||
|
||
return ( | ||
<> | ||
<Label id={selectId}>{label}</Label> | ||
<SelectButton | ||
aria-describedby={selectId} | ||
aria-haspopup="listbox" | ||
onClick={() => { | ||
setIsOpen(!isOpen); | ||
if (!isOpen) { | ||
onSelect(null); | ||
} | ||
}} | ||
> | ||
{selectedMachine?.hostname || Labels.ChooseMachine} | ||
</SelectButton> | ||
{isOpen ? <MachineSelectBox onSelect={handleSelect} /> : null} | ||
</> | ||
); | ||
}; | ||
|
||
export default MachineSelect; |
55 changes: 55 additions & 0 deletions
55
src/app/base/components/DhcpFormFields/MachineSelect/MachineSelectBox.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { useState } from "react"; | ||
|
||
import { SearchBox, Pagination } from "@canonical/react-components"; | ||
|
||
import { MachineSelectTable } from "app/base/components/MachineSelectTable/MachineSelectTable"; | ||
import type { Machine } from "app/store/machine/types"; | ||
import { FilterGroupKey } from "app/store/machine/types"; | ||
import { useFetchMachines } from "app/store/machine/utils/hooks"; | ||
|
||
const MachineSelectBox = ({ | ||
onSelect, | ||
}: { | ||
onSelect: (machine: Machine | null) => void; | ||
}): JSX.Element => { | ||
const pageSize = 15; | ||
const [searchText, setSearchText] = useState(""); | ||
const [currentPage, setPage] = useState(1); | ||
const { machines, machineCount, loading } = useFetchMachines({ | ||
currentPage, | ||
pageSize, | ||
filters: { [FilterGroupKey.FreeText]: searchText }, | ||
}); | ||
return ( | ||
<div className="source-machine-select" role="listbox"> | ||
<SearchBox | ||
autoComplete="off" | ||
autoFocus | ||
externallyControlled | ||
onChange={(searchText: string) => { | ||
setSearchText(searchText); | ||
}} | ||
placeholder="Search by hostname, system ID or tags" | ||
value={searchText} | ||
/> | ||
<div className="source-machine-select__table"> | ||
<MachineSelectTable | ||
machines={machines} | ||
machinesLoading={loading} | ||
onMachineClick={(machine) => { | ||
onSelect(machine); | ||
}} | ||
searchText={searchText} | ||
setSearchText={setSearchText} | ||
/> | ||
<Pagination | ||
currentPage={currentPage} | ||
itemsPerPage={pageSize} | ||
paginate={setPage} | ||
totalItems={machineCount || 0} | ||
/> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
export default MachineSelectBox; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from "./MachineSelect"; |
Oops, something went wrong.