diff --git a/src/components/create-vm-dialog/createVmDialog.jsx b/src/components/create-vm-dialog/createVmDialog.jsx index d1e9dfed1..5f21e2a78 100644 --- a/src/components/create-vm-dialog/createVmDialog.jsx +++ b/src/components/create-vm-dialog/createVmDialog.jsx @@ -21,9 +21,11 @@ import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import { debounce } from 'throttle-debounce'; import { Divider } from "@patternfly/react-core/dist/esm/components/Divider"; +import { FileUpload } from '@patternfly/react-core/dist/esm/components/FileUpload'; import { Flex, FlexItem } from "@patternfly/react-core/dist/esm/layouts/Flex"; import { Form, FormGroup } from "@patternfly/react-core/dist/esm/components/Form"; import { FormSelect, FormSelectOption } from "@patternfly/react-core/dist/esm/components/FormSelect"; +import { Grid, GridItem } from "@patternfly/react-core/dist/esm/layouts/Grid"; import { InputGroup } from "@patternfly/react-core/dist/esm/components/InputGroup"; import { Modal } from "@patternfly/react-core/dist/esm/components/Modal"; import { Select as PFSelect, SelectGroup, SelectOption } from "@patternfly/react-core/dist/esm/deprecated/components/Select"; @@ -33,7 +35,7 @@ import { Button } from "@patternfly/react-core/dist/esm/components/Button"; import { Tooltip } from "@patternfly/react-core/dist/esm/components/Tooltip"; import { TextArea } from "@patternfly/react-core/dist/esm/components/TextArea"; import { Spinner } from "@patternfly/react-core/dist/esm/components/Spinner"; -import { ExternalLinkAltIcon } from '@patternfly/react-icons'; +import { ExternalLinkAltIcon, MinusIcon } from '@patternfly/react-icons'; import { DialogsContext } from 'dialogs.jsx'; import cockpit from 'cockpit'; @@ -84,6 +86,7 @@ import { domainCreate } from '../../libvirtApi/domain.js'; import { storagePoolRefresh } from '../../libvirtApi/storagePool.js'; import { getAccessToken } from '../../libvirtApi/rhel-images.js'; import { PasswordFormFields, password_quality } from 'cockpit-components-password.jsx'; +import { DynamicListForm } from '../common/DynamicListForm'; import './createVmDialog.scss'; @@ -248,6 +251,8 @@ function validateParams(vmParams) { } if (vmParams.userPassword && !vmParams.userLogin) { validationFailed.userLogin = _("User login must not be empty when user password is set"); + } else if (vmParams.sshKeys.length > 0 && !vmParams.userLogin) { + validationFailed.userLogin = _("User login must not be empty when SSH keys are set"); } return validationFailed; @@ -748,6 +753,47 @@ const UsersConfigurationRow = ({ ); }; +const SshKeysRow = ({ + id, item, onChange, idx, removeitem, +}) => { + const [isLoading, setIsLoading] = useState(false); + + const handleClear = (_event) => { + onChange(idx, "file", ""); + onChange(idx, "value", ""); + }; + + return ( + + + onChange(idx, "file", file)} + onDataChange={(_event, value) => onChange(idx, "value", value)} + onTextChange={(_event, value) => onChange(idx, "value", value)} + onReadStarted={() => setIsLoading(true)} + onReadFinished={() => setIsLoading(false)} + onClearClick={_event => handleClear(_event)} + isLoading={isLoading} + allowEditingUploadedText + browseButtonText="Upload" /> + + +