From d4244a4abcd1f083e7007c4c4ee15107cac3230f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20D=C3=ADaz=20Gonz=C3=A1lez?= Date: Tue, 9 Apr 2024 17:35:27 +0100 Subject: [PATCH] web: Move storage/SpacePolicyField to its own file And adapts it to use a core/Field/SettingsField button. --- .../storage/ProposalSettingsSection.jsx | 71 +----------- .../components/storage/SpacePolicyField.jsx | 106 ++++++++++++++++++ web/src/components/storage/utils.js | 2 +- 3 files changed, 110 insertions(+), 69 deletions(-) create mode 100644 web/src/components/storage/SpacePolicyField.jsx diff --git a/web/src/components/storage/ProposalSettingsSection.jsx b/web/src/components/storage/ProposalSettingsSection.jsx index 3ae852af7b..57e10656d3 100644 --- a/web/src/components/storage/ProposalSettingsSection.jsx +++ b/web/src/components/storage/ProposalSettingsSection.jsx @@ -25,8 +25,9 @@ import React, { useEffect, useState } from "react"; import { Button, Checkbox, Form, Skeleton, Switch, Tooltip } from "@patternfly/react-core"; import { sprintf } from "sprintf-js"; -import { _, n_ } from "~/i18n"; -import { BootSelectionDialog, ProposalVolumes, SpacePolicyDialog } from "~/components/storage"; +import { _ } from "~/i18n"; +import { BootSelectionDialog, ProposalVolumes } from "~/components/storage"; +import SpacePolicyField from "~/components/storage/SpacePolicyField"; import { If, PasswordAndConfirmationInput, Section, Popup } from "~/components/core"; import { Icon } from "~/components/layout"; import { noop } from "~/utils"; @@ -337,72 +338,6 @@ const BootConfigField = ({ ); }; -/** - * Allows to select the space policy. - * @component - * - * @param {object} props - * @param {SpacePolicy|undefined} props.policy - * @param {SpaceAction[]} props.actions - * @param {StorageDevice[]} props.devices - * @param {boolean} props.isLoading - * @param {(config: SpacePolicyConfig) => void} props.onChange - * - * @typedef {object} SpacePolicyConfig - * @property {SpacePolicy} spacePolicy - * @property {SpaceAction[]} spaceActions - */ -const SpacePolicyField = ({ - policy, - actions, - devices, - isLoading, - onChange -}) => { - const [isDialogOpen, setIsDialogOpen] = useState(false); - - const openDialog = () => setIsDialogOpen(true); - - const closeDialog = () => setIsDialogOpen(false); - - const onAccept = ({ spacePolicy, spaceActions }) => { - closeDialog(); - onChange({ spacePolicy, spaceActions }); - }; - - const label = () => { - // eslint-disable-next-line agama-i18n/string-literals - if (policy.summaryLabels.length === 1) return _(policy.summaryLabels[0]); - - // eslint-disable-next-line agama-i18n/string-literals - return sprintf(n_(policy.summaryLabels[0], policy.summaryLabels[1], devices.length), devices.length); - }; - - if (isLoading || !policy) { - return ; - } - - return ( -
- {_("Find space")} - - - } - /> -
- ); -}; - /** * Section for editing the proposal settings * @component diff --git a/web/src/components/storage/SpacePolicyField.jsx b/web/src/components/storage/SpacePolicyField.jsx new file mode 100644 index 0000000000..a1bc41e64c --- /dev/null +++ b/web/src/components/storage/SpacePolicyField.jsx @@ -0,0 +1,106 @@ +/* + * Copyright (c) [2024] SUSE LLC + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact SUSE LLC. + * + * To contact SUSE LLC about this file by physical or electronic mail, you may + * find current contact information at www.suse.com. + */ + +// @ts-check + +import React, { useState } from "react"; +import { Skeleton } from "@patternfly/react-core"; + +import { sprintf } from "sprintf-js"; +import { _, n_ } from "~/i18n"; +import { If, SettingsField } from "~/components/core"; +import SpacePolicyDialog from "~/components/storage/SpacePolicyDialog"; + +/** + * @typedef {import ("~/client/storage").SpaceAction} SpaceAction + * @typedef {import ("~/components/storage/utils").SpacePolicy} SpacePolicy + * @typedef {import ("~/client/storage").StorageDevice} StorageDevice + * + * @typedef {object} SpacePolicyConfig + * @property {SpacePolicy} spacePolicy + * @property {SpaceAction[]} spaceActions + */ + +/** + * Allows to select the space policy. + * @component + * + * @param {object} props + * @param {SpacePolicy|undefined} props.policy + * @param {SpaceAction[]} props.actions + * @param {StorageDevice[]} props.devices + * @param {boolean} props.isLoading + * @param {(config: SpacePolicyConfig) => void} props.onChange + * + */ +export default function SpacePolicyField({ + policy, + actions, + devices, + isLoading, + onChange +}) { + const [isDialogOpen, setIsDialogOpen] = useState(false); + + const openDialog = () => setIsDialogOpen(true); + + const closeDialog = () => setIsDialogOpen(false); + + const onAccept = ({ spacePolicy, spaceActions }) => { + closeDialog(); + onChange({ spacePolicy, spaceActions }); + }; + + let value; + if (isLoading || !policy) { + value = ; + } else if (policy.summaryLabels.length === 1) { + // eslint-disable-next-line agama-i18n/string-literals + value = _(policy.summaryLabels[0]); + } else { + // eslint-disable-next-line agama-i18n/string-literals + value = sprintf(n_(policy.summaryLabels[0], policy.summaryLabels[1], devices.length), devices.length); + } + + return ( + + + } + /> + + ); +} diff --git a/web/src/components/storage/utils.js b/web/src/components/storage/utils.js index 6e45ad190c..1e842c211c 100644 --- a/web/src/components/storage/utils.js +++ b/web/src/components/storage/utils.js @@ -215,7 +215,7 @@ const deviceLabel = (device) => { const deviceChildren = (device) => { const partitionTableChildren = (partitionTable) => { const { partitions, unusedSlots } = partitionTable; - const children = partitions.concat(unusedSlots); + const children = partitions.concat(unusedSlots).filter(i => !!i); return children.sort((a, b) => a.start < b.start ? -1 : 1); };