summaryrefslogtreecommitdiffstats
path: root/src/ContainerRenameModal.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/ContainerRenameModal.jsx')
-rw-r--r--src/ContainerRenameModal.jsx107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/ContainerRenameModal.jsx b/src/ContainerRenameModal.jsx
new file mode 100644
index 0000000..d686412
--- /dev/null
+++ b/src/ContainerRenameModal.jsx
@@ -0,0 +1,107 @@
+import React, { useState } from 'react';
+import { Button } from "@patternfly/react-core/dist/esm/components/Button";
+import { Form, FormGroup } from "@patternfly/react-core/dist/esm/components/Form";
+import { Modal } from "@patternfly/react-core/dist/esm/components/Modal";
+import { TextInput } from "@patternfly/react-core/dist/esm/components/TextInput";
+import cockpit from 'cockpit';
+
+import * as client from './client.js';
+import * as utils from './util.js';
+import { ErrorNotification } from './Notification.jsx';
+import { useDialogs } from "dialogs.jsx";
+import { FormHelper } from 'cockpit-components-form-helper.jsx';
+
+const _ = cockpit.gettext;
+
+const ContainerRenameModal = ({ container, updateContainer }) => {
+ const Dialogs = useDialogs();
+ const [name, setName] = useState(container.Name);
+ const { version } = utils.usePodmanInfo();
+ const [nameError, setNameError] = useState(null);
+ const [dialogError, setDialogError] = useState(null);
+ const [dialogErrorDetail, setDialogErrorDetail] = useState(null);
+
+ const handleInputChange = (targetName, value) => {
+ if (targetName === "name") {
+ setName(value);
+ if (value === "") {
+ setNameError(_("Container name is required."));
+ } else if (utils.is_valid_container_name(value)) {
+ setNameError(null);
+ } else {
+ setNameError(_("Invalid characters. Name can only contain letters, numbers, and certain punctuation (_ . -)."));
+ }
+ }
+ };
+
+ const handleRename = () => {
+ if (!name) {
+ setNameError(_("Container name is required."));
+ return;
+ }
+
+ setNameError(null);
+ setDialogError(null);
+ client.renameContainer(container.isSystem, container.Id, { name })
+ .then(() => {
+ Dialogs.close();
+ // HACK: This is a workaround for missing API rename event in Podman versions less than 4.1.
+ if (version.localeCompare("4.1", undefined, { numeric: true, sensitivity: 'base' }) < 0) {
+ updateContainer(container.Id, container.isSystem); // not-covered: only on old version
+ }
+ })
+ .catch(ex => {
+ setDialogError(cockpit.format(_("Failed to rename container $0"), container.Name)); // not-covered: OS error
+ setDialogErrorDetail(cockpit.format("$0: $1", ex.message, ex.reason));
+ });
+ };
+
+ const handleKeyDown = (event) => {
+ if (event.key === "Enter") {
+ event.preventDefault();
+ handleRename();
+ }
+ };
+
+ const renameContent = (
+ <Form isHorizontal>
+ <FormGroup fieldId="rename-dialog-container-name" label={_("New container name")}>
+ <TextInput id="rename-dialog-container-name"
+ value={name}
+ validated={nameError ? "error" : "default"}
+ type="text"
+ aria-label={nameError}
+ onChange={(_, value) => handleInputChange("name", value)} />
+ <FormHelper fieldId="commit-dialog-image-name" helperTextInvalid={nameError} />
+ </FormGroup>
+ </Form>
+ );
+
+ return (
+ <Modal isOpen
+ position="top" variant="medium"
+ onClose={Dialogs.close}
+ onKeyDown={handleKeyDown}
+ title={cockpit.format(_("Rename container $0"), container.Name)}
+ footer={<>
+ <Button variant="primary"
+ className="btn-ctr-rename"
+ id="btn-rename-dialog-container"
+ isDisabled={nameError}
+ onClick={handleRename}>
+ {_("Rename")}
+ </Button>
+ <Button variant="link"
+ className="btn-ctr-cancel-commit"
+ onClick={Dialogs.close}>
+ {_("Cancel")}
+ </Button>
+ </>}
+ >
+ {dialogError && <ErrorNotification errorMessage={dialogError} errorDetail={dialogErrorDetail} onDismiss={() => setDialogError(null)} />}
+ {renameContent}
+ </Modal>
+ );
+};
+
+export default ContainerRenameModal;