LCOV - code coverage report
Current view: top level - pkg/shell - active-pages-modal.tsx Coverage Total Hit
Test: cockpit Lines: 96.2 % 80 77
Test Date: 2026-07-03 07:31:16

            Line data    Source code
       1              : /*
       2              :  * Copyright (C) 2021 Red Hat, Inc.
       3              :  * SPDX-License-Identifier: LGPL-2.1-or-later
       4              :  */
       5              : 
       6          341 : import cockpit from "cockpit";
       7              : 
       8          341 : import React, { useState } from "react";
       9              : import { ListingTable } from "cockpit-components-table.jsx";
      10              : import { Button } from "@patternfly/react-core/dist/esm/components/Button/index.js";
      11              : import { Label } from "@patternfly/react-core/dist/esm/components/Label/index.js";
      12              : import { Split, SplitItem } from "@patternfly/react-core/dist/esm/layouts/Split/index.js";
      13              : import {
      14              :     Modal,
      15              :     ModalBody,
      16              :     ModalFooter,
      17              :     ModalHeader
      18              : } from '@patternfly/react-core/dist/esm/components/Modal/index.js';
      19              : import { useInit } from "hooks";
      20              : import { DialogResult } from "dialogs";
      21              : 
      22              : import { ShellState } from "./state";
      23              : 
      24          341 : const _ = cockpit.gettext;
      25              : 
      26              : export interface ActivePagesDialogProps {
      27              :     dialogResult: DialogResult<void>;
      28              :     state: ShellState;
      29              : }
      30              : 
      31            1 : export const ActivePagesDialog = ({
      32            1 :     dialogResult,
      33            1 :     state
      34            1 : }: ActivePagesDialogProps) => {
      35            1 :     function get_pages() {
      36            1 :         const result = [];
      37            1 :         for (const frame of Object.values(state.frames)) {
      38            1 :             if (frame.url) {
      39            1 :                 const active = (frame == state.current_frame ||
      40            1 :                                 state.most_recent_path_for_host(frame.host) == frame.path);
      41            1 :                 result.push({
      42            1 :                     frame,
      43            1 :                     active,
      44            1 :                     selected: active,
      45            0 :                     displayName: frame.host === "localhost" ? "/" + frame.path : frame.host + ":/" + frame.path,
      46            1 :                 });
      47            1 :             }
      48            1 :         }
      49              : 
      50              :         // sort the frames by displayName, active ones first
      51            1 :         result.sort(function(a, b) {
      52            0 :             return (a.active ? -2 : 0) + (b.active ? 2 : 0) +
      53            1 :                    ((a.displayName < b.displayName) ? -1 : 0) + ((b.displayName < a.displayName) ? 1 : 0);
      54            1 :         });
      55              : 
      56            1 :         return result;
      57            1 :     }
      58              : 
      59            1 :     const init_pages = useInit(get_pages, [frames]);
      60            1 :     const [pages, setPages] = useState(init_pages);
      61              : 
      62            1 :     function onRemove() {
      63            1 :         pages.forEach(element => {
      64            1 :             if (element.selected) {
      65            1 :                 state.remove_frame(element.frame.name);
      66            1 :             }
      67            1 :         });
      68            1 :         dialogResult.resolve();
      69            1 :     }
      70              : 
      71            1 :     const rows = pages.map(page => {
      72            1 :         const columns = [{
      73            1 :             title: <Split>
      74            1 :                 <SplitItem isFilled>
      75            1 :                     {page.displayName}
      76            1 :                 </SplitItem>
      77            1 :                 <SplitItem>
      78            1 :                     {page.active && <Label color="blue">{_("active")}</Label>}
      79            1 :                 </SplitItem>
      80            1 :             </Split>,
      81            1 :         }];
      82            1 :         return ({
      83            1 :             props: {
      84            1 :                 key: page.frame.name,
      85            1 :                 'data-row-id': page.frame.name
      86            1 :             },
      87            1 :             columns,
      88            1 :             selected: page.selected,
      89            1 :         });
      90            1 :     });
      91              : 
      92            1 :     return (
      93            1 :         <Modal isOpen position="top" variant="small"
      94            1 :                id="active-pages-dialog"
      95            0 :                onClose={() => dialogResult.resolve()}
      96              :         >
      97            1 :             <ModalHeader title={_("Active pages")} />
      98            1 :             <ModalBody>
      99            1 :                 <ListingTable showHeader={false}
     100            1 :                               columns={[{ title: _("Page name") }]}
     101            1 :                               aria-label={_("Active pages")}
     102            1 :                               emptyCaption={ _("There are currently no active pages") }
     103            1 :                                   onSelect={(_event, isSelected, rowIndex) => {
     104            1 :                                       const new_pages = [...pages];
     105            1 :                                       new_pages[rowIndex].selected = isSelected;
     106            1 :                                       setPages(new_pages);
     107            1 :                                   }}
     108            1 :                               rows={rows} />
     109            1 :             </ModalBody>
     110            1 :             <ModalFooter>
     111            1 :                 <Button variant='primary' onClick={onRemove}>{_("Close selected pages")}</Button>
     112            1 :                 <Button variant='link' onClick={() => dialogResult.resolve()}>{_("Cancel")}</Button>
     113            1 :             </ModalFooter>
     114            1 :         </Modal>
     115              :     );
     116            1 : };
        

Generated by: LCOV version 2.0-1