• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / gui / 1057188406

01 Nov 2023 04:24AM UTC coverage: 82.824% (-17.1%) from 99.964%
1057188406

Pull #4134

gitlab-ci

web-flow
chore: Bump uuid from 9.0.0 to 9.0.1

Bumps [uuid](https://github.com/uuidjs/uuid) from 9.0.0 to 9.0.1.
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v9.0.0...v9.0.1)

---
updated-dependencies:
- dependency-name: uuid
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #4134: chore: Bump uuid from 9.0.0 to 9.0.1

4349 of 6284 branches covered (0.0%)

8313 of 10037 relevant lines covered (82.82%)

200.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.91
/src/js/components/common/dialogs/physicaldeviceonboarding.js
1
// Copyright 2019 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14
import React, { useEffect, useState } from 'react';
15
import { useDispatch, useSelector } from 'react-redux';
16
import { Link } from 'react-router-dom';
17

18
import { InfoOutlined as InfoIcon } from '@mui/icons-material';
19
import { Autocomplete, TextField } from '@mui/material';
20
import { createFilterOptions } from '@mui/material/useAutocomplete';
21

22
import { advanceOnboarding, setOnboardingApproach, setOnboardingDeviceType } from '../../../actions/onboardingActions';
23
import { EXTERNAL_PROVIDER } from '../../../constants/deviceConstants';
24
import { onboardingSteps } from '../../../constants/onboardingConstants';
25
import { getDebConfigurationCode, versionCompare } from '../../../helpers';
26
import { getFeatures, getFullVersionInformation, getIsEnterprise, getIsPreview, getOnboardingState, getOrganization } from '../../../selectors';
27
import { HELPTOOLTIPS, MenderHelpTooltip } from '../../helptips/helptooltips';
28
import CopyCode from '../copy-code';
29
import DocsLink from '../docslink';
30
import { MenderTooltipClickable } from '../mendertooltip';
31

32
const filter = createFilterOptions();
4✔
33

34
const types = [
4✔
35
  { title: 'Raspberry Pi 3', value: 'raspberrypi3' },
36
  { title: 'Raspberry Pi 4', value: 'raspberrypi4' }
37
];
38

39
export const ConvertedImageNote = () => (
4✔
40
  <p>
2✔
41
    We prepared an image, ready for Mender, for you to start with. You can find it in the{' '}
42
    <DocsLink path="get-started/preparation/prepare-a-raspberry-pi-device" title="Prepare a Raspberry Pi device" /> documentation, which also contains
43
    instructions for initial device setup. Once you&apos;re done flashing you can go ahead and proceed to the next step.
44
  </p>
45
);
46

47
const IntegrationsLink = () => (
4✔
48
  <Link to="/settings/integrations" target="_blank">
×
49
    Integration settings
50
  </Link>
51
);
52

53
export const ExternalProviderTip = ({ hasExternalIntegration, integrationProvider }) => (
4✔
54
  <MenderTooltipClickable
6✔
55
    className="clickable flexbox muted"
56
    placement="bottom"
57
    style={{ alignItems: 'end', marginBottom: 3 }}
58
    title={
59
      <div style={{ maxWidth: 350 }}>
60
        {hasExternalIntegration ? (
6✔
61
          <p>
62
            Devices added here will be automatically integrated with the <i>{EXTERNAL_PROVIDER[integrationProvider].title}</i> you set in the{' '}
63
            <IntegrationsLink />.
64
          </p>
65
        ) : (
66
          <p>
67
            To connect your devices with <i>{EXTERNAL_PROVIDER[integrationProvider].title}</i>, go to <IntegrationsLink /> and set up the integration.
68
          </p>
69
        )}
70
      </div>
71
    }
72
  >
73
    <InfoIcon />
74
  </MenderTooltipClickable>
75
);
76

77
export const DeviceTypeSelectionStep = ({
4✔
78
  hasConvertedImage,
79
  hasExternalIntegration,
80
  integrationProvider,
81
  onboardingState,
82
  onSelect,
83
  selection = '',
×
84
  version
85
}) => {
86
  const shouldShowOnboardingTip = !onboardingState.complete && onboardingState.showTips;
5✔
87
  const hasExternalIntegrationSupport = versionCompare(version, '3.2') > -1;
5✔
88
  return (
5✔
89
    <>
90
      <h4>Enter your device type</h4>
91
      <p>Setting this attribute on the device ensures that the device will only receive updates for compatible software releases.</p>
92

93
      <div style={{ display: 'grid', gridTemplateColumns: 'max-content 50px 150px', placeItems: 'end center' }}>
94
        <Autocomplete
95
          id="device-type-selection"
96
          autoSelect
97
          autoHighlight
98
          filterSelectedOptions
99
          freeSolo
100
          getOptionLabel={option => {
101
            // Value selected with enter, right from the input
102
            if (typeof option === 'string') {
9!
103
              return option;
9✔
104
            }
105
            if (option.key === 'custom' && option.value === selection) {
×
106
              return option.value;
×
107
            }
108
            return option.title;
×
109
          }}
110
          handleHomeEndKeys
111
          includeInputInList
112
          filterOptions={(options, params) => {
113
            const filtered = filter(options, params);
×
114
            if (filtered.length !== 1 && params.inputValue !== '') {
×
115
              filtered.push({
×
116
                value: params.inputValue,
117
                key: 'custom',
118
                title: `Use "${params.inputValue}"`
119
              });
120
            }
121
            return filtered;
×
122
          }}
123
          options={types}
124
          onChange={onSelect}
125
          renderInput={params => (
126
            <TextField {...params} label="Device type" placeholder="Choose a device type" InputProps={{ ...params.InputProps }} style={{ marginTop: 0 }} />
6✔
127
          )}
128
          style={{ maxWidth: 300 }}
129
          value={selection}
130
        />
131
        {hasExternalIntegrationSupport && <ExternalProviderTip hasExternalIntegration={hasExternalIntegration} integrationProvider={integrationProvider} />}
10✔
132
        {shouldShowOnboardingTip ? <MenderHelpTooltip id={HELPTOOLTIPS.deviceTypeTip.id} placement="bottom" /> : <div />}
5✔
133
      </div>
134
      {hasConvertedImage && <ConvertedImageNote />}
6✔
135
    </>
136
  );
137
};
138

139
export const InstallationStep = ({ advanceOnboarding, selection, onboardingState, ...remainingProps }) => {
4✔
140
  const codeToCopy = getDebConfigurationCode({ ...remainingProps, deviceType: selection, isOnboarding: !onboardingState.complete });
1✔
141
  return (
1✔
142
    <>
143
      <h4>Log into your device and install the Mender client</h4>
144
      <p>
145
        Copy & paste and run this command <b>on your device</b>:
146
      </p>
147
      <CopyCode code={codeToCopy} onCopy={() => advanceOnboarding(onboardingSteps.DASHBOARD_ONBOARDING_START)} withDescription={true} />
×
148
      <p>This downloads the Mender client on the device, sets the configuration and starts the client.</p>
149
      <p>
150
        Once the client has started, your device will attempt to connect to the server. It will then appear in your Pending devices tab and you can continue.
151
      </p>
152
    </>
153
  );
154
};
155

156
const steps = {
4✔
157
  1: DeviceTypeSelectionStep,
158
  2: InstallationStep
159
};
160

161
const integrationProvider = EXTERNAL_PROVIDER['iot-hub'].provider;
4✔
162

163
export const PhysicalDeviceOnboarding = ({ progress }) => {
4✔
164
  const [selection, setSelection] = useState('');
4✔
165
  const hasExternalIntegration = useSelector(state => {
4✔
166
    const { credentials = {} } = state.organization.externalDeviceIntegrations.find(integration => integration.provider === integrationProvider) ?? {};
8✔
167
    const { [EXTERNAL_PROVIDER['iot-hub'].credentialsAttribute]: azureConnectionString = '' } = credentials;
8✔
168
    return !!azureConnectionString;
8✔
169
  });
170
  const ipAddress = useSelector(state => state.app.hostAddress);
8✔
171
  const isEnterprise = useSelector(getIsEnterprise);
4✔
172
  const { isDemoMode, isHosted } = useSelector(getFeatures);
4✔
173
  const isPreRelease = useSelector(getIsPreview);
4✔
174
  const onboardingState = useSelector(getOnboardingState);
4✔
175
  const { tenant_token: tenantToken } = useSelector(getOrganization);
4✔
176
  const { Integration: version } = useSelector(getFullVersionInformation);
4✔
177
  const dispatch = useDispatch();
4✔
178

179
  useEffect(() => {
4✔
180
    dispatch(setOnboardingApproach('physical'));
2✔
181
  }, [dispatch]);
182

183
  const onSelect = (e, deviceType, reason) => {
4✔
184
    if (reason === 'selectOption') {
×
185
      dispatch(setOnboardingDeviceType(deviceType.value));
×
186
      setSelection(deviceType.value);
×
187
    } else if (reason === 'clear') {
×
188
      dispatch(setOnboardingDeviceType(''));
×
189
      setSelection('');
×
190
    }
191
  };
192

193
  const hasConvertedImage = !!selection && selection.length && (selection.startsWith('raspberrypi3') || selection.startsWith('raspberrypi4'));
4!
194

195
  const ComponentToShow = steps[progress];
4✔
196
  return (
4✔
197
    <ComponentToShow
198
      advanceOnboarding={step => dispatch(advanceOnboarding(step))}
×
199
      hasExternalIntegration={hasExternalIntegration}
200
      hasConvertedImage={hasConvertedImage}
201
      integrationProvider={integrationProvider}
202
      ipAddress={ipAddress}
203
      isEnterprise={isEnterprise}
204
      isHosted={isHosted}
205
      isDemoMode={isDemoMode}
206
      isPreRelease={isPreRelease}
207
      onboardingState={onboardingState}
208
      onSelect={onSelect}
209
      selection={selection}
210
      tenantToken={tenantToken}
211
      version={version}
212
    />
213
  );
214
};
215

216
export default PhysicalDeviceOnboarding;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc