-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Network improvements #1365
Merged
Merged
Network improvements #1365
Changes from 16 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
54c18ff
Notify DeviceStateReason changes and added brige device type
teclator 89a3a1a
fix(web): Redo the WiFi summary at NetworkPage
dgdavid adebdeb
fix(web): drop leftovers
dgdavid e49a5f6
First set of UI changes for wireless configuration
teclator edae23a
Moved the loadNetworks function to the network client
teclator e41c9dd
Make the WifiSelector stable enough
teclator 4398278
Fixes wifi selection UI problems
teclator 1ec7de6
[WIP] connecting to hidden form
teclator 5edc1d4
Fix form for connecting to a hidden WiFi
dgdavid 7ff00e1
Small network UI fixes
teclator ae5081b
Allow to edit a WiFi connection
teclator 6656e38
fix(web): goes back when after editing a connection
dgdavid b92f5e1
Use same approach than with WifiSelector for the NetworkPage.
teclator a406d77
Fixes for the NetworkPage wifi card
teclator 6fed0a0
Fix gateway4 field name
teclator f3062f4
Removed files added by error
teclator cba892a
Merge branch 'master' into network_improvements
teclator 1f80cd8
Removed unnecesary files
teclator 654e86c
Update web/src/components/network/NetworkPage.jsx
teclator d7b1a11
Added changes based on code review.
teclator c2340b7
Refresh the devices, connections and networks only when needed
teclator File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,32 +21,17 @@ | |
|
||
// @ts-check | ||
|
||
import React, { useEffect, useState } from "react"; | ||
import React, { useCallback, useEffect, useState } from "react"; | ||
import { Button, CardBody, Grid, GridItem, Split, Skeleton, Stack } from "@patternfly/react-core"; | ||
import { useLoaderData } from "react-router-dom"; | ||
import { Button, CardBody, Flex, Grid, GridItem, Skeleton, Stack } from "@patternfly/react-core"; | ||
import { useInstallerClient } from "~/context/installer"; | ||
import { CardField, Page } from "~/components/core"; | ||
import { ConnectionsTable, WifiSelector } from "~/components/network"; | ||
import { ButtonLink, CardField, EmptyState, Page } from "~/components/core"; | ||
import { ConnectionsTable } from "~/components/network"; | ||
import { NetworkEventTypes } from "~/client/network"; | ||
import { useInstallerClient } from "~/context/installer"; | ||
import { _ } from "~/i18n"; | ||
|
||
const WifiSelection = ({ wifiScanSupported }) => { | ||
const [wifiSelectorOpen, setWifiSelectorOpen] = useState(false); | ||
|
||
if (!wifiScanSupported) return; | ||
|
||
const openWifiSelector = () => setWifiSelectorOpen(true); | ||
const closeWifiSelector = () => setWifiSelectorOpen(false); | ||
|
||
return ( | ||
<> | ||
<Button variant="secondary" onClick={openWifiSelector}> | ||
{_("Connect to a Wi-Fi network")} | ||
</Button> | ||
<WifiSelector isOpen={wifiSelectorOpen} onClose={closeWifiSelector} /> | ||
</> | ||
); | ||
}; | ||
import { formatIp } from "~/client/network/utils"; | ||
import { sprintf } from "sprintf-js"; | ||
import { DeviceState } from "~/client/network/model"; | ||
|
||
/** | ||
* Internal component for displaying info when none wire connection is found | ||
|
@@ -58,135 +43,117 @@ const NoWiredConnections = () => { | |
); | ||
}; | ||
|
||
/** | ||
* Internal component for displaying info when none WiFi connection is found | ||
* @component | ||
* | ||
* @param {object} props | ||
* @param {boolean} props.supported - whether the system supports scanning WiFi networks | ||
* @param {boolean} props.openWifiSelector - the function for opening the WiFi selector | ||
*/ | ||
const NoWifiConnections = ({ wifiScanSupported }) => { | ||
const message = wifiScanSupported | ||
? _("The system has not been configured for connecting to a WiFi network yet.") | ||
: _("The system does not support WiFi connections, probably because of missing or disabled hardware."); | ||
|
||
return ( | ||
<Stack hasGutter> | ||
<div>{_("No WiFi connections found.")}</div> | ||
<div>{message}</div> | ||
</Stack> | ||
); | ||
}; | ||
|
||
/** | ||
* Page component holding Network settings | ||
* @component | ||
*/ | ||
export default function NetworkPage() { | ||
const { network: client } = useInstallerClient(); | ||
const { connections: initialConnections, settings } = useLoaderData(); | ||
const { connections: initialConnections, devices: initialDevices, settings } = useLoaderData(); | ||
const [connections, setConnections] = useState(initialConnections); | ||
const [devices, setDevices] = useState(undefined); | ||
const [selectedConnection, setSelectedConnection] = useState(null); | ||
const [devices, setDevices] = useState(initialDevices); | ||
const [updateState, setUpdateState] = useState(false); | ||
|
||
useEffect(() => { | ||
return client.onNetworkChange(({ type, payload }) => { | ||
switch (type) { | ||
case NetworkEventTypes.DEVICE_ADDED: { | ||
setDevices((devs) => { | ||
const newDevices = devs.filter((d) => d.name !== payload.name); | ||
return [...newDevices, client.fromApiDevice(payload)]; | ||
}); | ||
break; | ||
} | ||
const fetchState = useCallback(async () => { | ||
const devices = await client.devices(); | ||
const connections = await client.connections(); | ||
setDevices(devices); | ||
setConnections(connections); | ||
}, [client]); | ||
|
||
case NetworkEventTypes.DEVICE_UPDATED: { | ||
const [name, data] = payload; | ||
setDevices(devs => { | ||
const newDevices = devs.filter((d) => d.name !== name); | ||
return [...newDevices, client.fromApiDevice(data)]; | ||
}); | ||
break; | ||
} | ||
useEffect(() => { | ||
fetchState(); | ||
setUpdateState(false); | ||
}, [fetchState, updateState]); | ||
|
||
case NetworkEventTypes.DEVICE_REMOVED: { | ||
setDevices(devs => devs.filter((d) => d.name !== payload)); | ||
break; | ||
} | ||
useEffect(() => { | ||
return client.onNetworkChange(({ type }) => { | ||
if ([NetworkEventTypes.DEVICE_ADDED, NetworkEventTypes.DEVICE_UPDATED, NetworkEventTypes.DEVICE_REMOVED].includes(type)) { | ||
setUpdateState(true); | ||
} | ||
client.connections().then(setConnections); | ||
}); | ||
}, [client, devices]); | ||
|
||
useEffect(() => { | ||
if (devices !== undefined) return; | ||
}); | ||
|
||
client.devices().then(setDevices); | ||
}, [client, devices]); | ||
|
||
const selectConnection = ({ id }) => { | ||
client.getConnection(id).then(setSelectedConnection); | ||
}; | ||
const connectionDevice = ({ id }) => devices?.find(({ connection }) => id === connection); | ||
const connectionAddresses = (connection) => { | ||
const device = connectionDevice(connection); | ||
const addresses = device ? device.addresses : connection.addresses; | ||
|
||
const forgetConnection = async ({ id }) => { | ||
await client.deleteConnection(id); | ||
setConnections(undefined); | ||
}; | ||
|
||
const updateConnections = async () => { | ||
setConnections(undefined); | ||
setDevices(undefined); | ||
return addresses?.map(formatIp).join(", "); | ||
}; | ||
|
||
const ready = (connections !== undefined) && (devices !== undefined); | ||
|
||
const WifiConnections = () => { | ||
const wifiConnections = connections.filter(c => c.wireless); | ||
const { wireless_enabled: wifiAvailable } = settings; | ||
|
||
if (wifiConnections.length === 0) { | ||
if (!wifiAvailable) { | ||
return ( | ||
<NoWifiConnections wifiScanSupported={settings.wireless_enabled} /> | ||
<CardField> | ||
<CardField.Content> | ||
<EmptyState title={_("No WiFi support")} icon="wifi_off" color="warning-color-200"> | ||
teclator marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{_("The system does not support WiFi connections, probably because of missing or disabled hardware.")} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Put in the shoes of an inexperienced user... I do not know if "missing hardware" is good enough. |
||
</EmptyState> | ||
</CardField.Content> | ||
</CardField> | ||
); | ||
} | ||
|
||
const wifiConnections = connections.filter(c => c.wireless); | ||
const activeWifiDevice = devices.find(d => d.type === "wireless" && d.state === "activated"); | ||
const activeConnection = wifiConnections.find(c => c.id === activeWifiDevice?.connection); | ||
|
||
return ( | ||
<ConnectionsTable connections={wifiConnections} devices={devices} onEdit={selectConnection} onForget={forgetConnection} /> | ||
<CardField | ||
label={_("Wi-Fi")} | ||
actions={ | ||
<ButtonLink isPrimary={!activeConnection} to="wifis"> | ||
{activeConnection ? _("Change") : _("Connect")} | ||
</ButtonLink> | ||
} | ||
> | ||
<CardField.Content> | ||
{activeConnection | ||
? ( | ||
<EmptyState title={sprintf(_("Conected to %s"), activeConnection.id)} icon="wifi" color="success-color-100"> | ||
{connectionAddresses(activeConnection)} | ||
</EmptyState> | ||
) | ||
: ( | ||
<EmptyState title={_("No connected yet")} icon="wifi_off" color="color-300"> | ||
{_("The system has not been configured for connecting to a WiFi network yet.")} | ||
teclator marked this conversation as resolved.
Show resolved
Hide resolved
|
||
</EmptyState> | ||
)} | ||
</CardField.Content> | ||
</CardField> | ||
); | ||
}; | ||
|
||
const WiredConnections = () => { | ||
const wiredConnections = connections.filter(c => !c.wireless && (c.id !== "lo")); | ||
const wiredConnections = connections.filter(c => !c.wireless); | ||
|
||
if (wiredConnections.length === 0) return <NoWiredConnections />; | ||
|
||
return <ConnectionsTable connections={wiredConnections} devices={devices} onEdit={selectConnection} />; | ||
return <ConnectionsTable connections={wiredConnections} devices={devices} />; | ||
}; | ||
|
||
return ( | ||
<> | ||
<Page.Header> | ||
<Flex justifyContent={{ default: "justifyContentSpaceBetween" }}> | ||
<h2>{_("Network")}</h2> | ||
<WifiSelection wifiScanSupported={settings.wireless_enabled} /> | ||
</Flex> | ||
<h2>{_("Network")}</h2> | ||
</Page.Header> | ||
|
||
<Page.MainContent> | ||
<Grid hasGutter> | ||
<GridItem sm={12}> | ||
<CardField label={_("Wired connections")}> | ||
<GridItem sm={12} xl={6}> | ||
<CardField label={_("Wired")}> | ||
<CardBody> | ||
{ready ? <WiredConnections /> : <Skeleton />} | ||
</CardBody> | ||
</CardField> | ||
</GridItem> | ||
<GridItem sm={12}> | ||
<CardField label={_("WiFi connections")}> | ||
<CardBody> | ||
{ready ? <WifiConnections /> : <Skeleton />} | ||
</CardBody> | ||
</CardField> | ||
<GridItem sm={12} xl={6}> | ||
<WifiConnections /> | ||
</GridItem> | ||
</Grid> | ||
</Page.MainContent> | ||
|
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is
updateState
used? Perhaps a better name could help to know the intention.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it was updateNetworks, as the method was get from WifiSelector and updateDevicesConnections was like too much.. was not very inspired at the moment of writing it :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed offline, it is wrong because we are not checking the
updateState
value.