Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions pkg/lib/anaconda/_anaconda.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
--pf-v6-c-page--BackgroundColor: var(--pf-t--global--background--color--primary--default);
}

.pf-v6-c-card {
--pf-v6-c-card--BorderColor: transparent;
}
// .pf-v6-c-card {
// --pf-v6-c-card--BorderColor: transparent;
// }

// Approximates PageSection padding={{ default: "noPadding" }} isFilled={false} (PF .pf-m-no-padding / .pf-m-no-fill)
.pf-v6-c-page__main-section {
Expand Down
5 changes: 5 additions & 0 deletions pkg/networkmanager/anaconda-main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#network-interface {
.pf-v6-c-card.pf-m-plain .pf-v6-c-card__header, .pf-v6-c-card.pf-m-plain > .pf-v6-c-card__title {
padding-block-start: 0;
}
}
182 changes: 182 additions & 0 deletions pkg/networkmanager/anaconda-main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/*
* Copyright (C) 2021 Red Hat, Inc.
* SPDX-License-Identifier: LGPL-2.1-or-later
*/

import cockpit from "cockpit";
import React, { useState } from 'react';

import { Flex, FlexItem } from "@patternfly/react-core/dist/esm/layouts/Flex/index.js";
import { Page, } from "@patternfly/react-core/dist/esm/components/Page/index.js";

import { ListingTableRowProps } from "cockpit-components-table.jsx";

import {
has_group,
is_loopback,
is_managed,
is_wireless,
render_active_connection,
} from './interfaces.js';
import { Content, ContentVariants, SimpleList, SimpleListGroup, SimpleListItem, Split, SplitItem } from "@patternfly/react-core";
import { NetworkInterfacePage } from "./network-interface.jsx";
import "./anaconda-main.css";

const _ = cockpit.gettext;

interface AnacondaNetworkPageProps {
privileged: boolean;
operationInProgress: boolean;
usage_monitor: any;
interfaces: any[];
iface?: any;
}

interface AnacondaActiveNetwork {
isWireless?: boolean;
iface: any;
}

export const AnacondaNetworkPage = ({ privileged, operationInProgress, usage_monitor, interfaces }: AnacondaNetworkPageProps) => {
const [active, setActive] = useState<AnacondaActiveNetwork>();
Comment on lines +40 to +41

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 2 added lines are not executed by any test. Details

// useEvent(usage_monitor.grid, "notify");

const managedWired: ListingTableRowProps[] = [];
const managedWireless: ListingTableRowProps[] = [];
let hasDetails = false;

Check notice

Code scanning / CodeQL

Unused variable, import, function or class Note

Unused variable hasDetails.
Comment on lines +44 to +46

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 3 added lines are not executed by any test. Details


interfaces.forEach(iface => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This added line is not executed by any test. Details

// Skip loopback
if (is_loopback(iface))
return;
Comment on lines +50 to +51

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 2 added lines are not executed by any test. Details


// Skip members
else if (has_group(iface))
return;
Comment on lines +54 to +55

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 2 added lines are not executed by any test. Details


const dev = iface.Device;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This added line is not executed by any test. Details

// const show_traffic = (dev && (dev.State == 100 || dev.State == 10) && dev.Carrier === true);

// usage_monitor.add(iface.Name);

const activeConnection = render_active_connection(dev, false, true);
const isWireless = is_wireless(iface);
Comment on lines +62 to +63

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 2 added lines are not executed by any test. Details


let connectionStatus;
if (activeConnection) {
connectionStatus = _("Connected")
Comment on lines +65 to +67

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 3 added lines are not executed by any test. Details

} else {
connectionStatus = _("Disconnected")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This added line is not executed by any test. Details

}

const row = (
<SimpleListItem key={iface.name} onClick={() => {setActive({isWireless, iface})}}>
<Flex
direction={{ default: 'row' }}
justifyContent={{ default: 'justifyContentSpaceBetween' }}
flexWrap={{ default: 'nowrap' }}
Comment on lines +72 to +77

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 6 added lines are not executed by any test. Details

>
<FlexItem flex={{ default: 'flex_1' }}>{iface.Name}</FlexItem>
<FlexItem>
<Content component={ContentVariants.small}>{connectionStatus}</Content>
</FlexItem>
</Flex>
</SimpleListItem>
)

// Details column: show type-specific information
// let detailsColumn = null;
// if (dev?.DeviceType === '802-11-wireless') {
// const networkCount = dev.visibleSsids.length;
// if (networkCount > 0 || dev.ActiveAccessPoint?.Ssid) {
// hasDetails = true;
// detailsColumn = (
// <Flex columnGap={{ default: 'columnGapSm' }}>
// {networkCount > 0 && (
// <FlexItem>
// <Label status="info">
// {cockpit.format(cockpit.ngettext("$0 network", "$0 networks", networkCount), networkCount)}
// </Label>
// </FlexItem>
// )}
// {dev.ActiveAccessPoint?.Ssid && (
// <FlexItem>
// <Label status="success" icon={<ConnectedIcon />}>{dev.ActiveAccessPoint?.Ssid}</Label>
// </FlexItem>
// )}
// </Flex>
// );
// }
// }
// row.columns.push({ title: detailsColumn });

if (!dev || is_managed(dev)) {
isWireless ? managedWireless.push(row) : managedWired.push(row);
}
});

// TODO: Actions: turn on off action and edit (wired) or join wifi (wireless)
const actions = privileged && (

Check notice

Code scanning / CodeQL

Unused variable, import, function or class Note

Unused variable actions.
<>
{/* <NetworkAction buttonText={_("Add VPN")} type='wg' />
<NetworkAction buttonText={_("Add bond")} type='bond' />
<NetworkAction buttonText={_("Add team")} type='team' />
<NetworkAction buttonText={_("Add bridge")} type='bridge' />
<NetworkAction buttonText={_("Add VLAN")} type='vlan' /> */}
</>
);

return (
<Page data-test-wait={operationInProgress} id="networking" className="pf-m-no-sidebar anaconda">
<Content component="h1">{_("Networks")}</Content>
<Split hasGutter>
<SplitItem>
<SimpleList>
{managedWireless.length !== 0 && (
<SimpleListGroup title={_("Wireless")} id="wireless-connections">{...managedWireless}</SimpleListGroup>
)}
{managedWired.length !== 0 && (
<SimpleListGroup title={_("Wired")} id="wired-connections">{...managedWired}</SimpleListGroup>
)}
{(managedWireless.length === 0 && managedWired.length === 0) && (
<SimpleListItem key="not-found">{_("No networks found")}</SimpleListItem>
)}
</SimpleList>
</SplitItem>
<SplitItem isFilled>
{active?.iface &&
<NetworkInterfacePage
privileged={privileged}
operationInProgress={operationInProgress}
usage_monitor={usage_monitor}
plot_state={undefined}
interfaces={interfaces}
iface={active.iface} />
}
</SplitItem>
</Split>

</Page>
);
};

export const AnacondaWirelessDetail = ({active}: {active: AnacondaActiveNetwork}) => {
return <>
<Content component="h2">{_("Wireless")}</Content>
Interface
{active.iface.Name}
Status
Network joined
Security type
</>
}

export const AnacondaWiredDetail = ({active}: {active: AnacondaActiveNetwork}) => {
return <>
<Content component="h2">{_("Wired")}</Content>
Interface
{active.iface.Name}
Status
IP Settings
</>
}
18 changes: 18 additions & 0 deletions pkg/networkmanager/interfaces.js
Original file line number Diff line number Diff line change
Expand Up @@ -2105,6 +2105,24 @@ export function apply_group_member(choices, model, apply_group, group_connection
});
}

export function is_loopback(iface) {
return iface.Name == "lo" || (iface.Device && iface.Device.DeviceType == "loopback");
}

export function has_group(iface) {
return (
(iface.Device &&
iface.Device.ActiveConnection &&
iface.Device.ActiveConnection.Group &&
iface.Device.ActiveConnection.Group.Members.length > 0) ||
(iface.MainConnection && iface.MainConnection.Groups.length > 0)
);
}

export function is_wireless(iface) {
return iface.Device?.DeviceType === '802-11-wireless';
}

export function init() {
cockpit.translate();
}
Loading
Loading