Line data Source code
1 : /*
2 : * Copyright (C) 2026 Red Hat, Inc.
3 : * SPDX-License-Identifier: LGPL-2.1-or-later
4 : */
5 :
6 37 : import cockpit from "cockpit";
7 37 : import React, { useState } from 'react';
8 :
9 : import { Flex, FlexItem } from "@patternfly/react-core/dist/esm/layouts/Flex/index.js";
10 : import { Page, } from "@patternfly/react-core/dist/esm/components/Page/index.js";
11 :
12 : import {
13 : has_group,
14 : is_loopback,
15 : is_managed,
16 : is_wireless,
17 : render_active_connection,
18 : } from './interfaces.js';
19 : import { Content, ContentVariants, SimpleList, SimpleListGroup, SimpleListItem, Split, SplitItem } from "@patternfly/react-core";
20 : import { NetworkInterfacePage } from "./network-interface.jsx";
21 : import "./anaconda-main.css";
22 : import { EmptyStatePanel } from "cockpit-components-empty-state.js";
23 :
24 37 : const _ = cockpit.gettext;
25 :
26 : interface AnacondaNetworkPageProps {
27 : privileged: boolean;
28 : operationInProgress: boolean;
29 : usage_monitor: any;
30 : interfaces: any[];
31 : iface?: any;
32 : }
33 :
34 : interface AnacondaActiveNetwork {
35 : isWireless?: boolean;
36 : iface: any;
37 : }
38 :
39 0 : export const AnacondaNetworkPage = ({ privileged, operationInProgress, usage_monitor, interfaces }: AnacondaNetworkPageProps) => {
40 0 : const [active, setActive] = useState<AnacondaActiveNetwork>();
41 :
42 0 : const managedWired: React.ReactNode[] = [];
43 0 : const managedWireless: React.ReactNode[] = [];
44 :
45 0 : interfaces.forEach(iface => {
46 : // Skip loopback
47 0 : if (is_loopback(iface))
48 0 : return;
49 :
50 : // Skip members
51 0 : else if (has_group(iface))
52 0 : return;
53 :
54 0 : const dev = iface.Device;
55 :
56 0 : const activeConnection = render_active_connection(dev, false, true);
57 0 : const isWireless = is_wireless(iface);
58 :
59 0 : let connectionStatus;
60 0 : if (activeConnection) {
61 0 : connectionStatus = _("Connected")
62 0 : } else {
63 0 : connectionStatus = _("Disconnected")
64 0 : }
65 :
66 0 : const row = (
67 0 : <SimpleListItem key={iface.name} onClick={() => {setActive({isWireless, iface})}}>
68 0 : <Flex
69 0 : direction={{ default: 'row' }}
70 0 : justifyContent={{ default: 'justifyContentSpaceBetween' }}
71 0 : flexWrap={{ default: 'nowrap' }}
72 : >
73 0 : <FlexItem flex={{ default: 'flex_1' }}>{iface.Name}</FlexItem>
74 0 : <FlexItem>
75 0 : <Content component={ContentVariants.small}>{connectionStatus}</Content>
76 0 : </FlexItem>
77 0 : </Flex>
78 0 : </SimpleListItem>
79 : )
80 :
81 0 : if (!dev || is_managed(dev)) {
82 0 : isWireless ? managedWireless.push(row) : managedWired.push(row);
83 0 : }
84 0 : });
85 :
86 0 : return (
87 0 : <Page data-test-wait={operationInProgress} id="networking" className="pf-m-no-sidebar anaconda">
88 0 : <Content component="h1">{_("Networks")}</Content>
89 0 : <Split hasGutter>
90 0 : <SplitItem>
91 0 : <SimpleList>
92 0 : {managedWireless.length !== 0 && (
93 0 : <SimpleListGroup title={_("Wireless")} id="wireless-connections">{...managedWireless}</SimpleListGroup>
94 : )}
95 0 : {managedWired.length !== 0 && (
96 0 : <SimpleListGroup title={_("Wired")} id="wired-connections">{...managedWired}</SimpleListGroup>
97 : )}
98 0 : {(managedWireless.length === 0 && managedWired.length === 0) && (
99 0 : <SimpleListItem key="not-found">{_("No networks found")}</SimpleListItem>
100 : )}
101 0 : </SimpleList>
102 0 : </SplitItem>
103 0 : <SplitItem isFilled>
104 0 : {active?.iface ?
105 0 : <NetworkInterfacePage
106 0 : privileged={privileged}
107 0 : operationInProgress={operationInProgress}
108 0 : usage_monitor={usage_monitor}
109 0 : plot_state={undefined}
110 0 : interfaces={interfaces}
111 0 : iface={active.iface} /> :
112 0 : <EmptyStatePanel
113 0 : title={_("No network selected.")}
114 0 : paragraph={_("Select a network interface to configure the connection.")}
115 0 : />
116 : }
117 0 : </SplitItem>
118 0 : </Split>
119 :
120 0 : </Page>
121 : );
122 0 : };
|