summaryrefslogtreecommitdiffstats
path: root/src/ContainerRenameModal.jsx
blob: d6864126a117a56a0d5dc1247a9716c817358a4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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;