Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue#932 #1007

Merged
merged 28 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d4759e5
#932_to_Select
nagu165 Dec 26, 2023
7b8722f
Formselect was changed
nagu165 Dec 30, 2023
2ad5599
Replaced mountpoint selctor with text
nagu165 Jan 1, 2024
f8f95ff
Merge pull request #1 from openSUSE/master
nagu165 Jan 1, 2024
e2fc75e
minor errors fixed
nagu165 Jan 2, 2024
403b6b4
Merge https://github.com/nagu165/agama into issue#932
nagu165 Jan 2, 2024
1648d8c
Merge branch 'issue#932' of https://github.com/nagu165/agama into iss…
nagu165 Jan 2, 2024
96b8b87
fixed some errors 2
nagu165 Jan 2, 2024
3fb9d26
mountpoint modified
nagu165 Jan 9, 2024
927352b
changed L78
nagu165 Jan 9, 2024
46adca2
Updating the MountPointFormSelect component to use the more powerful …
nagu165 Jan 9, 2024
66d4207
Updated the MountPointFormSelect component to use Select component in…
nagu165 Jan 10, 2024
8bbbb5d
Revert "minor errors fixed"
nagu165 Jan 10, 2024
4908d56
Merge branch 'openSUSE:master' into issue#932
nagu165 Jan 10, 2024
bb79e2c
Update VolumeForm.jsx
nagu165 Jan 10, 2024
fbae8f5
[web] Update storage/VolumeForm component tests
dgdavid Jan 11, 2024
3571e85
[web] Fix indentation
dgdavid Jan 11, 2024
679b5b5
[web] Drop not expected prop for PF/Select component
dgdavid Jan 11, 2024
afca5cf
[web] Fix storage/VolumesForm#MountPointSelector widget
dgdavid Jan 11, 2024
8db198e
[web] Update storage/ProposalVolumes component test
dgdavid Jan 11, 2024
1e0bcb3
Updated the code to show '*' next to the MountPoint field only when t…
nagu165 Jan 16, 2024
827a1d8
Updated the code to show '*' only when the mountpoint field is editable
nagu165 Jan 16, 2024
6b00245
Merge branch 'openSUSE:master' into issue#932
nagu165 Jan 16, 2024
b73a4a6
Updated the code to remove an unrequired prop
nagu165 Jan 17, 2024
a68be13
Merge branch 'issue#932' of https://github.com/nagu165/agama into iss…
nagu165 Jan 17, 2024
7a9e06d
Updated Changelog file with the changes made in the current PR.
nagu165 Jan 19, 2024
3e93780
Resolving the merge conflicts by pulling fromm upstream.
nagu165 Jan 19, 2024
ddfef10
Update web/package/cockpit-agama.changes
dgdavid Jan 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions web/package/cockpit-agama.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
-------------------------------------------------------------------
Fri Jan 19 09:34:26 UTC 2024 - Nagu <[email protected]>

- Storage UI: show mount point selector only when the user can change it.
(gh#openSUSE/agama#1007)

-------------------------------------------------------------------
Thu Jan 18 08:33:52 UTC 2024 - Ancor Gonzalez Sosa <[email protected]>

Expand Down
2 changes: 0 additions & 2 deletions web/src/components/storage/ProposalVolumes.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,6 @@ describe("if there are volumes", () => {

const popup = await screen.findByRole("dialog");
within(popup).getByText("Edit file system");
const mountPointSelector = within(popup).getByRole("combobox", { name: "Mount point" });
expect(mountPointSelector).toHaveAttribute("disabled");
});

describe("and there is transactional Btrfs volume", () => {
Expand Down
86 changes: 70 additions & 16 deletions web/src/components/storage/VolumeForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,55 @@ const SizeUnitFormSelect = ({ units, ...formSelectProps }) => {
* Based on {@link PF/FormSelect https://www.patternfly.org/components/forms/form-select}
*
* @param {object} props
* @param {string} props.value - mountPath of current selected volume
* @param {Array<Volume>} props.volumes - a collection of storage volumes
* @param {object} props.formSelectProps - @see {@link https://www.patternfly.org/components/forms/form-select#props}
* @param {onChangeFn} props.onChange - callback for notifying input changes
* @param {object} props.selectProps - other props sent to {@link https://www.patternfly.org/components/menus/select#props PF/Select}
* @returns {ReactComponent}
*/
const MountPointFormSelect = ({ volumes, ...formSelectProps }) => {
*/

const MountPointFormSelect = ({ value, volumes, onChange, ...selectProps }) => {
const [isOpen, setIsOpen] = useState(false);

const onSelect = (_, mountPath) => {
setIsOpen(false);
onChange(mountPath);
};

const onToggleClick = () => {
setIsOpen(!isOpen);
};

const toggle = toggleRef => {
return (
<MenuToggle
id="mountPoint"
ref={toggleRef}
onClick={onToggleClick}
isExpanded={isOpen}
className="full-width"
>
{value || _("Select a value")}
</MenuToggle>
);
};
return (
<FormSelect { ...formSelectProps }>
{ volumes.map(v => <FormSelectOption key={v.mountPath} value={v.mountPath} label={v.mountPath} />) }
</FormSelect>
<Select
onOpenChange={setIsOpen}
onSelect={onSelect}
isOpen={isOpen}
toggle={toggle}
shouldFocusToggleOnSelect
{ ...selectProps }
>
<SelectList>
{volumes.map(v => (
<SelectOption isSelected={value === v.mountPath} key={v.mountPath} value={v.mountPath}>
{v.mountPath}
</SelectOption>
))}
</SelectList>
</Select>
);
};

Expand Down Expand Up @@ -676,7 +716,7 @@ const reducer = (state, action) => {
export default function VolumeForm({ id, volume: currentVolume, templates = [], onSubmit }) {
const [state, dispatch] = useReducer(reducer, currentVolume || templates[0], createInitialState);

const changeVolume = (_, mountPath) => {
const changeVolume = (mountPath) => {
const volume = templates.find(t => t.mountPath === mountPath);
dispatch({ type: "CHANGE_VOLUME", payload: { volume } });
};
Expand Down Expand Up @@ -722,17 +762,31 @@ export default function VolumeForm({ id, volume: currentVolume, templates = [],

const { fsType, snapshots } = state.formData;

const ShowMountPointSelector = () => (
<MountPointFormSelect
value={state.formData.mountPoint}
onChange={changeVolume}
volumes={currentVolume ? [currentVolume] : templates}
/>
);

const ShowMountPoint = () => <p>{state.formData.mountPoint}</p>;

return (
<Form id={id} onSubmit={submitForm}>
<FormGroup isRequired label={_("Mount point")} fieldId="mountPoint">
<MountPointFormSelect
id="mountPoint"
value={state.formData.mountPoint}
onChange={changeVolume}
volumes={currentVolume ? [currentVolume] : templates}
isDisabled={currentVolume !== undefined}
/>
</FormGroup>
<If
condition={currentVolume !== undefined}
then={
<FormGroup label={_("Mount point")}>
<ShowMountPoint />
</FormGroup>
}
else={
<FormGroup isRequired label={_("Mount point")} fieldId="mountPoint">
<ShowMountPointSelector />
</FormGroup>
}
/>
<FsField
value={{ fsType, snapshots }}
volume={state.volume}
Expand Down
48 changes: 28 additions & 20 deletions web/src/components/storage/VolumeForm.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,6 @@ beforeEach(() => {
props = { templates: [volumes.root, volumes.home, volumes.swap] };
});

it("renders a control for displaying/selecting the mount point", () => {
plainRender(<VolumeForm {...props} />);

screen.getByRole("combobox", { name: "Mount point" });
});

it("renders a control for displaying/selecting the file system type", async () => {
const { user } = plainRender(<VolumeForm {...props} />);

Expand All @@ -113,9 +107,10 @@ it("renders a control for displaying/selecting the file system type", async () =
it("does not render the file system control if there is only one option", async () => {
const { user } = plainRender(<VolumeForm {...props} />);

const mountPointSelector = screen.getByRole("combobox", { name: "Mount point" });
const swap = within(mountPointSelector).getByRole("option", { name: "swap" });
await user.selectOptions(mountPointSelector, swap);
const mountPointButton = screen.getByRole("button", { name: "Mount point" });
await user.click(mountPointButton);
const swap = screen.getByRole("option", { name: "swap" });
await user.click(swap);
await screen.findByText("Swap");
await waitFor(() => (
expect(screen.queryByRole("button", { name: "File system type" })).not.toBeInTheDocument())
Expand Down Expand Up @@ -151,12 +146,13 @@ it("renders the 'Auto' size option only when a volume with 'adaptive sizes' is s
// that it's configured for allowing adaptive sizes too.
screen.getByRole("radio", { name: "Auto" });

const mountPointSelector = screen.getByRole("combobox", { name: "Mount point" });
const homeVolumeOption = screen.getByRole("option", { name: "/home" });
const mountPointButton = screen.getByRole("button", { name: "Mount point" });
await user.click(mountPointButton);

// And we know that /home volume is not set to allow adaptive sizes. Thus,
// let's select it.
await user.selectOptions(mountPointSelector, homeVolumeOption);
const homeVolumeOption = screen.getByRole("option", { name: "/home" });
await user.click(homeVolumeOption);

const autoSizeOption = screen.queryByRole("radio", { name: "Auto" });
expect(autoSizeOption).toBeNull();
Expand Down Expand Up @@ -296,19 +292,31 @@ describe("size validations", () => {
describe("when editing a new volume", () => {
beforeEach(() => { props.volume = volumes.root });

it("renders the mount point selector as disabled", () => {
it("renders the mount point", () => {
plainRender(<VolumeForm {...props} />);

const mountPointSelector = screen.getByRole("combobox", { name: "Mount point" });
expect(mountPointSelector).toBeDisabled();
screen.getByText("/");
});
});

describe("when adding a new volume", () => {
it("renders the mount point selector as enabled", () => {
it("does not render a control for changing the mount point", async () => {
plainRender(<VolumeForm {...props} />);
await waitFor(() => (
expect(screen.queryByRole("button", { name: "Mount point" })).not.toBeInTheDocument()
));
});
});

const mountPointSelector = screen.getByRole("combobox", { name: "Mount point" });
expect(mountPointSelector).toBeEnabled();
describe("when adding a new volume", () => {
it("renders a control for setting the mount point", async () => {
const { user } = plainRender(<VolumeForm {...props} />);

let mountPointButton = screen.getByRole("button", { name: "Mount point" });
await user.click(mountPointButton);
screen.getByRole("option", { name: "/" });
screen.getByRole("option", { name: "swap" });
const homeMountPoint = screen.getByRole("option", { name: "/home" });
await user.click(homeMountPoint);
mountPointButton = screen.getByRole("button", { name: "Mount point" });
await within(mountPointButton).findByText("/home");
});
});