Line data Source code
1 43 : import React, { useState } from 'react';
2 :
3 : import { Button } from "@patternfly/react-core/dist/esm/components/Button";
4 : import { Form, FormGroup } from "@patternfly/react-core/dist/esm/components/Form";
5 : import { TextInput } from "@patternfly/react-core/dist/esm/components/TextInput";
6 : import {
7 : Modal
8 : } from '@patternfly/react-core/dist/esm/deprecated/components/Modal';
9 : import { FormHelper } from 'cockpit-components-form-helper.jsx';
10 : import { useDialogs } from "dialogs.jsx";
11 :
12 : import cockpit from 'cockpit';
13 :
14 : import { ErrorNotification } from './Notification.jsx';
15 : import * as client from './client.js';
16 : import * as utils from './util.js';
17 :
18 43 : const _ = cockpit.gettext;
19 :
20 2 : const ContainerRenameModal = ({ con, container, updateContainer }) => {
21 2 : const Dialogs = useDialogs();
22 2 : const [name, setName] = useState(container.Name);
23 2 : const { version } = utils.usePodmanInfo();
24 2 : const [nameError, setNameError] = useState(null);
25 2 : const [dialogError, setDialogError] = useState(null);
26 2 : const [dialogErrorDetail, setDialogErrorDetail] = useState(null);
27 :
28 2 : const handleInputChange = (targetName, value) => {
29 2 : if (targetName === "name") {
30 2 : setName(value);
31 2 : if (value === "") {
32 2 : setNameError(_("Container name is required."));
33 2 : } else if (utils.is_valid_container_name(value)) {
34 2 : setNameError(null);
35 2 : } else {
36 2 : setNameError(_("Invalid characters. Name can only contain letters, numbers, and certain punctuation (_ . -)."));
37 2 : }
38 2 : }
39 2 : };
40 :
41 2 : const handleRename = () => {
42 2 : if (!name) {
43 2 : setNameError(_("Container name is required."));
44 2 : return;
45 2 : }
46 :
47 2 : setNameError(null);
48 2 : setDialogError(null);
49 2 : client.renameContainer(con, container.Id, { name })
50 2 : .then(() => {
51 2 : Dialogs.close();
52 : // HACK: This is a workaround for missing API rename event in Podman versions less than 4.1.
53 0 : if (version.localeCompare("4.1", undefined, { numeric: true, sensitivity: 'base' }) < 0) {
54 0 : updateContainer(con, container.Id); // not-covered: only on old version
55 0 : }
56 2 : })
57 0 : .catch(ex => {
58 0 : setDialogError(cockpit.format(_("Failed to rename container $0"), container.Name)); // not-covered: OS error
59 0 : setDialogErrorDetail(cockpit.format("$0: $1", ex.message, ex.reason));
60 0 : });
61 2 : };
62 :
63 2 : const handleKeyDown = (event) => {
64 2 : if (event.key === "Enter") {
65 2 : event.preventDefault();
66 2 : handleRename();
67 2 : }
68 2 : };
69 :
70 2 : const renameContent = (
71 2 : <Form isHorizontal>
72 2 : <FormGroup fieldId="rename-dialog-container-name" label={_("New container name")}>
73 2 : <TextInput id="rename-dialog-container-name"
74 2 : value={name}
75 2 : validated={nameError ? "error" : "default"}
76 2 : type="text"
77 2 : aria-label={nameError}
78 2 : onChange={(_, value) => handleInputChange("name", value)} />
79 2 : <FormHelper fieldId="commit-dialog-image-name" helperTextInvalid={nameError} />
80 2 : </FormGroup>
81 2 : </Form>
82 : );
83 :
84 2 : return (
85 2 : <Modal isOpen
86 2 : position="top" variant="medium"
87 2 : onClose={Dialogs.close}
88 2 : onKeyDown={handleKeyDown}
89 2 : title={cockpit.format(_("Rename container $0"), container.Name)}
90 2 : footer={<>
91 2 : <Button variant="primary"
92 2 : className="btn-ctr-rename"
93 2 : id="btn-rename-dialog-container"
94 2 : isDisabled={nameError}
95 2 : onClick={handleRename}>
96 2 : {_("Rename")}
97 2 : </Button>
98 2 : <Button variant="link"
99 2 : className="btn-ctr-cancel-commit"
100 2 : onClick={Dialogs.close}>
101 2 : {_("Cancel")}
102 2 : </Button>
103 2 : </>}
104 : >
105 0 : {dialogError && <ErrorNotification errorMessage={dialogError} errorDetail={dialogErrorDetail} onDismiss={() => setDialogError(null)} />}
106 2 : {renameContent}
107 2 : </Modal>
108 : );
109 2 : };
110 :
111 43 : export default ContainerRenameModal;
|