LCOV - code coverage report
Current view: top level - src - ContainerRenameModal.jsx Coverage Total Hit
Test: cockpit-podman Lines: 90.4 % 83 75
Test Date: 2025-05-21 17:35:03

            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;
        

Generated by: LCOV version 2.0-1