LCOV - code coverage report
Current view: top level - pkg/networkmanager - networkmanager.jsx Coverage Total Hit
Test: cockpit Lines: 99.0 % 102 101
Test Date: 2026-07-13 10:00:01

            Line data    Source code
       1              : /*
       2              :  * Copyright (C) 2021 Red Hat, Inc.
       3              :  * SPDX-License-Identifier: LGPL-2.1-or-later
       4              :  */
       5              : import '../lib/patternfly/patternfly-6-cockpit.scss';
       6              : import "./network-anaconda.scss";
       7           37 : import cockpit from "cockpit";
       8              : import 'cockpit-dark-theme'; // once per page
       9           37 : import React, { useRef } from 'react';
      10           37 : import { createRoot } from "react-dom/client";
      11              : 
      12              : import { Button } from "@patternfly/react-core/dist/esm/components/Button/index.js";
      13              : import { ExclamationCircleIcon } from "@patternfly/react-icons";
      14              : 
      15              : import { EmptyStatePanel } from "cockpit-components-empty-state.jsx";
      16              : import { ModelContext } from './model-context.jsx';
      17              : import { NetworkInterfacePage } from './network-interface.jsx';
      18              : import { NetworkPage } from './network-main.jsx';
      19              : import { UsageMonitor } from './helpers.js';
      20              : 
      21              : import * as service from 'service.js';
      22              : import { init as initDialogs, NetworkManagerModel } from './interfaces.js';
      23              : import { superuser } from 'superuser';
      24              : import { PlotState } from 'plot';
      25              : 
      26              : import { useObject, useEvent, usePageLocation } from "hooks";
      27              : import { WithDialogs } from "dialogs.jsx";
      28              : 
      29           37 : const _ = cockpit.gettext;
      30              : 
      31           37 : const App = () => {
      32           37 :     const nmService = useObject(() => service.proxy("NetworkManager"),
      33           37 :                                 null,
      34           37 :                                 []);
      35           37 :     useEvent(nmService, "changed");
      36              : 
      37           37 :     const model = useObject(() => new NetworkManagerModel(), null, []);
      38           37 :     useEvent(model, "changed");
      39              : 
      40           37 :     const nmRunning_ref = useRef(undefined);
      41           37 :     useEvent(model.client, "owner", (event, owner) => { nmRunning_ref.current = owner !== null });
      42              : 
      43           37 :     const { path } = usePageLocation();
      44              : 
      45           37 :     useEvent(superuser, "changed");
      46              : 
      47           37 :     const usage_monitor = useObject(() => new UsageMonitor(), null, []);
      48           37 :     const plot_state_main = useObject(() => new PlotState(), null, []);
      49           37 :     const plot_state_iface = useObject(() => new PlotState(), null, []);
      50              : 
      51           10 :     if (model.curtain == 'testing' || model.curtain == 'restoring') {
      52           10 :         return <EmptyStatePanel loading title={model.curtain == 'testing' ? _("Testing connection") : _("Restoring connection")} />;
      53           10 :     }
      54              : 
      55           37 :     if (model.ready === undefined)
      56           37 :         return <EmptyStatePanel loading />;
      57              : 
      58              :     /* Show EmptyStatePanel when nm is not running */
      59            8 :     if (!nmRunning_ref.current) {
      60            8 :         if (nmService.enabled) {
      61            8 :             return (
      62            8 :                 <div id="networking-nm-crashed">
      63            8 :                     <EmptyStatePanel icon={ ExclamationCircleIcon }
      64            8 :                                      title={ _("NetworkManager is not running") }
      65            7 :                                      action={nmService.exists ? _("Start service") : null}
      66            8 :                                      onAction={ nmService.start }
      67            8 :                                      secondary={
      68            8 :                                          <Button component="a"
      69            8 :                                                  variant="secondary"
      70            1 :                                                  onClick={() => cockpit.jump("/system/services#/NetworkManager.service", cockpit.transport.host)}>
      71            8 :                                              {_("Troubleshoot…")}
      72            8 :                                          </Button>
      73            8 :                                      } />
      74            8 :                 </div>
      75              :             );
      76            8 :         } else if (!nmService.exists) {
      77            8 :             return (
      78            8 :                 <div id="networking-nm-not-found">
      79            8 :                     <EmptyStatePanel icon={ ExclamationCircleIcon }
      80            8 :                                      title={ _("NetworkManager is not installed") } />
      81              : 
      82            8 :                 </div>
      83              :             );
      84            8 :         } else {
      85            8 :             return (
      86            8 :                 <div id="networking-nm-disabled">
      87            8 :                     <EmptyStatePanel icon={ ExclamationCircleIcon }
      88            8 :                                      title={ _("Network devices and graphs require NetworkManager") }
      89            7 :                                      action={nmService.exists ? _("Enable service") : null}
      90            1 :                                      onAction={() => {
      91            1 :                                          nmService.enable();
      92            1 :                                          nmService.start();
      93            1 :                                      }} />
      94              : 
      95            8 :                 </div>
      96              :             );
      97            8 :         }
      98            8 :     }
      99              : 
     100           37 :     const interfaces = model.list_interfaces();
     101              : 
     102              :     /* At this point NM is running and the model is ready */
     103           36 :     if (path.length == 0) {
     104           36 :         return (
     105           36 :             <ModelContext.Provider value={model}>
     106           36 :                 <WithDialogs key="1">
     107           36 :                     <NetworkPage privileged={superuser.allowed}
     108           36 :                                  operationInProgress={model.operationInProgress}
     109           36 :                                  usage_monitor={usage_monitor}
     110           36 :                                  plot_state={plot_state_main}
     111           36 :                                  interfaces={interfaces} />
     112           36 :                 </WithDialogs>
     113           36 :             </ModelContext.Provider>
     114              :         );
     115           33 :     } else if (path.length == 1) {
     116           31 :         const iface = interfaces.find(iface => iface.Name == path[0]);
     117              : 
     118           34 :         if (iface) {
     119           34 :             return (
     120           34 :                 <ModelContext.Provider value={model}>
     121           34 :                     <WithDialogs key="2">
     122           34 :                         <NetworkInterfacePage privileged={superuser.allowed}
     123           34 :                                               operationInProgress={model.operationInProgress}
     124           34 :                                               usage_monitor={usage_monitor}
     125           34 :                                               plot_state={plot_state_iface}
     126           34 :                                               interfaces={interfaces}
     127           34 :                                               iface={iface} />
     128           34 :                     </WithDialogs>
     129           34 :                 </ModelContext.Provider>
     130              :             );
     131            8 :         } else {
     132            8 :             return (
     133            8 :                 <EmptyStatePanel icon={ ExclamationCircleIcon }
     134            8 :                                  title={cockpit.format(_("Network interface '$0' not found"), path[0])}
     135            8 :                                  action={_("Return to overview page")}
     136            8 :                                  actionVariant="link"
     137            0 :                                  onAction={() => cockpit.location.go("/")}
     138            8 :                 />
     139              :             );
     140            8 :         }
     141           34 :     }
     142              : 
     143            7 :     return null;
     144           37 : };
     145              : 
     146           37 : function init() {
     147           37 :     initDialogs();
     148           37 :     const root = createRoot(document.getElementById("network-page"));
     149           37 :     root.render(<App />);
     150           37 : }
     151              : 
     152           37 : document.addEventListener("DOMContentLoaded", init);
        

Generated by: LCOV version 2.0-1