Skip to content
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

Unset wifi profile from managed gateway connection settings #7315

Merged
merged 8 commits into from
Sep 20, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -147,16 +147,14 @@ describe('Managed Gateway connection settings', () => {
it('succeeds to display UI elements in place', () => {
cy.findByText('WiFi connection', { selector: 'h3' }).should('be.visible')
cy.findByText('Ethernet connection', { selector: 'h3' }).should('be.visible')
cy.findByText('Connection settings profiles can be shared within the same organization').should(
'be.visible',
)
cy.findByLabelText('Show profiles of').should('have.attr', 'disabled')
cy.findByText('Enable WiFi connection').should('be.visible')
cy.findByRole('button', { name: 'Save changes' }).should('be.visible')

cy.findByText(gatewayVersionIds.model_id, { selector: 'h3' }).should('be.visible')
})

it('succeeds to set WiFi connection with already created profile', () => {
cy.findByLabelText(/Enable WiFi connection/).check()
cy.findByLabelText('Settings profile').selectOption(wifiProfileId)
cy.findByText(
'Please click "Save changes" to start using this WiFi profile for the gateway',
Expand All @@ -176,7 +174,26 @@ describe('Managed Gateway connection settings', () => {
.and('contain', 'Connection settings updated')
})

it('succeeds to update connection settings with disabled WiFi connection', () => {
cy.findByRole('button', { name: 'Save changes' }).click()
cy.wait('@update-connection-settings')
.its('request.body')
.should(body => {
expect(body).to.have.nested.property('gateway.wifi_profile_id', null)
})
cy.findByText('The gateway WiFi is currently attempting to connect using this profile').should(
'not.exist',
)
cy.findByTestId('error-notification').should('not.exist')
cy.findByTestId('toast-notification-success')
.should('be.visible')
.and('contain', 'Connection settings updated')
})

it('succeeds to validate new WiFi profile fields', () => {
cy.findByLabelText(/Enable WiFi connection/).check()
cy.findByRole('button', { name: 'Save changes' }).click()
cy.get('#wifi_profile\\.profile_id-field-error').should('be.visible')
cy.findByLabelText('Settings profile').selectOption('shared')
cy.wait('@scan-access-points')
cy.findByLabelText(/Use default network interface settings/).uncheck()
Expand All @@ -194,6 +211,7 @@ describe('Managed Gateway connection settings', () => {
})

it('succeeds to set WiFi connection with new shared profile', () => {
cy.findByLabelText(/Enable WiFi connection/).check()
cy.findByLabelText('Settings profile').selectOption('shared')
cy.wait('@scan-access-points')
cy.findByLabelText('Profile name').type('New WiFi profile')
Expand All @@ -217,6 +235,7 @@ describe('Managed Gateway connection settings', () => {
})

it('succeeds to set WiFi connection with new non-shared profile', () => {
cy.findByLabelText(/Enable WiFi connection/).check()
cy.findByLabelText('Settings profile').selectOption('non-shared')
cy.wait('@scan-access-points')
cy.findByText('AccessPoint1').click()
Expand Down Expand Up @@ -300,6 +319,7 @@ describe('Managed Gateway connection settings', () => {
},
})
cy.reload()
cy.findByLabelText(/Enable WiFi connection/).check()
cy.findByLabelText('Show profiles of').should('not.have.attr', 'disabled')
cy.findByLabelText('Show profiles of').selectOption(organizationId)
cy.findByLabelText('Settings profile').selectOption(wifiProfileId)
Expand Down
2 changes: 1 addition & 1 deletion pkg/gatewayconfigurationserver/managed/mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ func fromProfileID(profileID string) []byte {

func fromProfileIDOrNil(profileID string) *northboundv1.ProfileIDValue {
if profileID == "" {
return nil
return new(northboundv1.ProfileIDValue)
}
id := uuid.Must(uuid.Parse(profileID))
return &northboundv1.ProfileIDValue{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import NetworkInterfaceAddressesFormFields from '@console/containers/gateway-man

const m = defineMessages({
ethernetConnection: 'Ethernet connection',
enableEthernetConnection: 'Enable ethernet connection',
useStaticIp: 'Use a static IP address',
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ const GatewayConnectionSettings = () => {
...(isNonSharedProfile && { ...profile.data }),
profile_id: isNonSharedProfile ? 'non-shared' : selectedManagedGateway.wifi_profile_id ?? '',
_override: !Boolean(profile) && hasWifiProfileSet,
_enable_wifi_connection: Boolean(profile),
_profile_of: entityId ?? '',
}),
[hasWifiProfileSet, selectedManagedGateway.wifi_profile_id],
Expand Down Expand Up @@ -247,7 +248,8 @@ const GatewayConnectionSettings = () => {
const handleSubmit = useCallback(
async (values, { resetForm, setSubmitting }, cleanValues) => {
const getWifiProfileId = async (profile, shouldUpdateNonSharedWifiProfile) => {
const { profile_id, _profile_of, _override, ...wifiProfile } = profile
const { profile_id, _profile_of, _override, _enable_wifi_connection, ...wifiProfile } =
profile
let wifiProfileId = profile_id
// If the WiFi profile id contains 'shared', create/update that profile.
// The id could be either shared or non-shared.
Expand Down Expand Up @@ -311,15 +313,18 @@ const GatewayConnectionSettings = () => {
const { wifi_profile, ethernet_profile } = values

const shouldUpdateNonSharedWifiProfile =
wifi_profile.profile_id === 'non-shared' && Boolean(nonSharedWifiProfileId)
wifi_profile.profile_id === 'non-shared' &&
Boolean(nonSharedWifiProfileId) &&
wifi_profile._enable_wifi_connection

const wifiProfileId = await getWifiProfileId(wifi_profile, shouldUpdateNonSharedWifiProfile)
const ethernetProfileId = await getEthernetProfileId(
ethernet_profile,
cleanValues.ethernet_profile,
)
const body = {
...(Boolean(wifiProfileId) && { wifi_profile_id: wifiProfileId }),
wifi_profile_id:
!wifi_profile._enable_wifi_connection && !wifi_profile._override ? null : wifiProfileId,
ethernet_profile_id: ethernetProfileId,
}

Expand All @@ -331,6 +336,7 @@ const GatewayConnectionSettings = () => {
resetValues = {
...values,
wifi_profile: {
...values.wifi_profile,
...initialWifiProfile,
profile_id: wifiProfileId,
_profile_of: wifi_profile._profile_of,
Expand All @@ -342,7 +348,10 @@ const GatewayConnectionSettings = () => {
resetForm({
values: resetValues,
})
setSaveFormClicked(true)

if (resetValues.wifi_profile._enable_wifi_connection) {
setSaveFormClicked(true)
}

toast({
title: selectedGateway.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ import {
} from '@console/containers/gateway-managed-gateway/shared/validation-schema'

import Yup from '@ttn-lw/lib/yup'
import sharedMessages from '@ttn-lw/lib/shared-messages'

export const validationSchema = Yup.object().shape({
wifi_profile: Yup.object()
.shape({
_override: Yup.boolean().default(false),
profile_id: Yup.string(),
_enable_wifi_connection: Yup.boolean().default(false),
profile_id: Yup.string().when('_enable_wifi_connection', {
is: true,
then: schema => schema.required().required(sharedMessages.validateRequired),
}),
})
.when('.profile_id', {
is: profileId => profileId && profileId.includes('shared'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import Notification from '@ttn-lw/components/notification'
import Button from '@ttn-lw/components/button'
import Link from '@ttn-lw/components/link'
import toast from '@ttn-lw/components/toast'
import Checkbox from '@ttn-lw/components/checkbox'

import Message from '@ttn-lw/lib/components/message'
import RequireRequest from '@ttn-lw/lib/components/require-request'
Expand Down Expand Up @@ -73,6 +74,7 @@ const m = defineMessages({
settingsProfileTooltip:
'To set up the gateway connection, you can either use a shared profile, to share the connection settings with other gateways, or set a config for this gateway only.',
fetchProfilesFailure: 'There was an error and the WiFi profiles cannot be fetched.',
enableWifiConnection: 'Enable WiFi connection',
})

const WifiSettingsFormFields = ({ initialValues, isWifiConnected, saveFormClicked }) => {
Expand Down Expand Up @@ -103,7 +105,7 @@ const WifiSettingsFormFields = ({ initialValues, isWifiConnected, saveFormClicke
]

const connectionStatus = useMemo(() => {
if (!values.wifi_profile.profile_id) return null
if (!values.wifi_profile.profile_id || !values.wifi_profile._enable_wifi_connection) return null
if (hasChanged) {
return { message: m.saveToConnect, icon: <Icon icon={IconInfoCircle} /> }
}
Expand Down Expand Up @@ -147,6 +149,7 @@ const WifiSettingsFormFields = ({ initialValues, isWifiConnected, saveFormClicke
hasChanged,
isWifiConnected,
saveFormClicked,
values.wifi_profile._enable_wifi_connection,
values.wifi_profile._override,
values.wifi_profile.profile_id,
])
Expand Down Expand Up @@ -209,41 +212,65 @@ const WifiSettingsFormFields = ({ initialValues, isWifiConnected, saveFormClicke
[setValues],
)

const handleEnableWifiChange = useCallback(() => {
const { _profile_of, ...initialProfile } = initialWifiProfile
setValues(oldValues => ({
...oldValues,
wifi_profile: {
...oldValues.wifi_profile,
...initialProfile,
},
}))
}, [setValues])

return (
<>
<Message component="h3" content={m.wifiConnection} className="mt-0" />
{!values.wifi_profile._override ? (
<>
<div className="d-flex al-center gap-cs-m">
<ShowProfilesSelect name={`wifi_profile._profile_of`} onChange={handleChangeProfile} />
{Boolean(values.wifi_profile._profile_of) && (
<RequireRequest
requestAction={getConnectionProfilesList({
entityId: values.wifi_profile._profile_of,
type: CONNECTION_TYPES.WIFI,
})}
handleErrors={false}
>
<Form.Field
name={`wifi_profile.profile_id`}
title={m.settingsProfile}
component={Select}
options={profileOptions}
tooltip={m.settingsProfileTooltip}
placeholder={m.selectAProfile}
onChange={handleProfileIdChange}
required
/>
</RequireRequest>
)}
</div>
<Message
component="div"
content={m.profileDescription}
className={style.fieldDescription}
<Form.Field
name={`wifi_profile._enable_wifi_connection`}
component={Checkbox}
label={m.enableWifiConnection}
onChange={handleEnableWifiChange}
/>
{values.wifi_profile.profile_id.includes('shared') && (
<GatewayWifiProfilesFormFields namePrefix={`wifi_profile.`} />
{values.wifi_profile._enable_wifi_connection && (
<>
<div className="d-flex al-center gap-cs-m">
<ShowProfilesSelect
name={`wifi_profile._profile_of`}
onChange={handleChangeProfile}
/>
{Boolean(values.wifi_profile._profile_of) && (
<RequireRequest
requestAction={getConnectionProfilesList({
entityId: values.wifi_profile._profile_of,
type: CONNECTION_TYPES.WIFI,
})}
handleErrors={false}
>
<Form.Field
name={`wifi_profile.profile_id`}
title={m.settingsProfile}
component={Select}
options={profileOptions}
tooltip={m.settingsProfileTooltip}
placeholder={m.selectAProfile}
onChange={handleProfileIdChange}
required
/>
</RequireRequest>
)}
</div>
<Message
component="div"
content={m.profileDescription}
className={style.fieldDescription}
/>
{values.wifi_profile.profile_id.includes('shared') && (
<GatewayWifiProfilesFormFields namePrefix={`wifi_profile.`} />
)}
</>
)}
</>
) : (
Expand Down Expand Up @@ -284,6 +311,7 @@ const WifiSettingsFormFields = ({ initialValues, isWifiConnected, saveFormClicke
WifiSettingsFormFields.propTypes = {
initialValues: PropTypes.shape({
wifi_profile: PropTypes.shape({
_enable_wifi_connection: PropTypes.bool,
_override: PropTypes.bool,
profile_id: PropTypes.string,
_profile_of: PropTypes.string,
Expand Down
2 changes: 1 addition & 1 deletion pkg/webui/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,6 @@
"console.containers.gateway-managed-gateway.connection-settings.connections.messages.connectedVia": "Connected via {connectedVia}",
"console.containers.gateway-managed-gateway.connection-settings.connections.messages.cpuTemperature": "CPU temperature: {temperature}",
"console.containers.gateway-managed-gateway.connection-settings.ethernet-settings-form-fields.ethernetConnection": "Ethernet connection",
"console.containers.gateway-managed-gateway.connection-settings.ethernet-settings-form-fields.enableEthernetConnection": "Enable ethernet connection",
"console.containers.gateway-managed-gateway.connection-settings.ethernet-settings-form-fields.useStaticIp": "Use a static IP address",
"console.containers.gateway-managed-gateway.connection-settings.index.firstNotification": "You have just claimed a managed gateway. To connect it to WiFi or ethernet you can configure those connections here. The preprovisioned cellular backhaul typically connects automatically.",
"console.containers.gateway-managed-gateway.connection-settings.index.updateSuccess": "Connection settings updated",
Expand All @@ -592,6 +591,7 @@
"console.containers.gateway-managed-gateway.connection-settings.wifi-settings-form-fields.attemptingToConnect": "The gateway WiFi is currently attempting to connect using this profile",
"console.containers.gateway-managed-gateway.connection-settings.wifi-settings-form-fields.settingsProfileTooltip": "To set up the gateway connection, you can either use a shared profile, to share the connection settings with other gateways, or set a config for this gateway only.",
"console.containers.gateway-managed-gateway.connection-settings.wifi-settings-form-fields.fetchProfilesFailure": "There was an error and the WiFi profiles cannot be fetched.",
"console.containers.gateway-managed-gateway.connection-settings.wifi-settings-form-fields.enableWifiConnection": "Enable WiFi connection",
"console.containers.gateway-managed-gateway.shared.network-interface-addresses-form-fields.ipAddresses": "IP addresses",
"console.containers.gateway-managed-gateway.shared.network-interface-addresses-form-fields.dnsServers": "DNS servers",
"console.containers.gateway-managed-gateway.shared.network-interface-addresses-form-fields.addServerAddress": "Add server address",
Expand Down
2 changes: 1 addition & 1 deletion pkg/webui/locales/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,6 @@
"console.containers.gateway-managed-gateway.connection-settings.connections.messages.connectedVia": "",
"console.containers.gateway-managed-gateway.connection-settings.connections.messages.cpuTemperature": "",
"console.containers.gateway-managed-gateway.connection-settings.ethernet-settings-form-fields.ethernetConnection": "",
"console.containers.gateway-managed-gateway.connection-settings.ethernet-settings-form-fields.enableEthernetConnection": "",
"console.containers.gateway-managed-gateway.connection-settings.ethernet-settings-form-fields.useStaticIp": "",
"console.containers.gateway-managed-gateway.connection-settings.index.firstNotification": "",
"console.containers.gateway-managed-gateway.connection-settings.index.updateSuccess": "",
Expand All @@ -592,6 +591,7 @@
"console.containers.gateway-managed-gateway.connection-settings.wifi-settings-form-fields.attemptingToConnect": "",
"console.containers.gateway-managed-gateway.connection-settings.wifi-settings-form-fields.settingsProfileTooltip": "",
"console.containers.gateway-managed-gateway.connection-settings.wifi-settings-form-fields.fetchProfilesFailure": "",
"console.containers.gateway-managed-gateway.connection-settings.wifi-settings-form-fields.enableWifiConnection": "",
"console.containers.gateway-managed-gateway.shared.network-interface-addresses-form-fields.ipAddresses": "",
"console.containers.gateway-managed-gateway.shared.network-interface-addresses-form-fields.dnsServers": "",
"console.containers.gateway-managed-gateway.shared.network-interface-addresses-form-fields.addServerAddress": "",
Expand Down
Loading