@nordicsemiconductor/pc-nrfconnect-shared 121.0.0 → 122.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Changelog.md +34 -0
- package/coverage/cobertura-coverage.xml +1330 -1197
- package/nrfutil/device/__mocks__/device.ts +2 -0
- package/nrfutil/device/batch.ts +18 -2
- package/nrfutil/device/common.ts +17 -38
- package/nrfutil/device/device.ts +2 -0
- package/nrfutil/device/deviceInfo.ts +70 -0
- package/nrfutil/device/erase.ts +2 -2
- package/nrfutil/device/firmwareRead.ts +2 -2
- package/nrfutil/device/getCoreInfo.ts +2 -2
- package/nrfutil/device/getFwInfo.ts +2 -2
- package/nrfutil/device/getProtectionStatus.ts +2 -2
- package/nrfutil/device/list.ts +4 -30
- package/nrfutil/device/program.ts +4 -4
- package/nrfutil/device/recover.ts +2 -2
- package/nrfutil/device/reset.ts +2 -2
- package/nrfutil/device/setMcuState.ts +2 -5
- package/nrfutil/device/setProtectionStatus.ts +2 -2
- package/nrfutil/index.ts +1 -1
- package/nrfutil/moduleVersion.ts +20 -0
- package/nrfutil/sandboxTypes.ts +14 -0
- package/package.json +1 -1
- package/src/About/DeviceCard.tsx +6 -5
- package/src/About/SupportCard.tsx +2 -2
- package/src/Device/DeviceSelector/BasicDeviceInfo.tsx +12 -6
- package/src/Device/DeviceSelector/DeviceList/AnimatedList.tsx +1 -1
- package/src/Device/DeviceSelector/DeviceList/Device.tsx +7 -5
- package/src/Device/DeviceSelector/DeviceList/DeviceList.tsx +23 -5
- package/src/Device/DeviceSelector/DeviceList/EditDeviceButtons.tsx +7 -6
- package/src/Device/DeviceSelector/DeviceList/MoreDeviceInfo.tsx +26 -30
- package/src/Device/DeviceSelector/DeviceList/edit-device-buttons.scss +1 -2
- package/src/Device/DeviceSelector/DeviceSelector.test.tsx +17 -37
- package/src/Device/DeviceSelector/DeviceSelector.tsx +38 -13
- package/src/Device/DeviceSelector/Favorite.tsx +10 -10
- package/src/Device/DeviceSelector/basic-device-info.scss +0 -12
- package/src/Device/deviceInfo/deviceInfo.ts +2 -2
- package/src/Device/deviceLister.ts +52 -43
- package/src/Device/deviceSetup.ts +27 -10
- package/src/Device/deviceSlice.ts +148 -84
- package/src/Device/jprogOperations.ts +56 -27
- package/src/Device/sdfuOperations.ts +25 -31
- package/src/InlineInput/NumberInlineInput.tsx +1 -1
- package/src/InlineInput/NumberInputWithDropdown.tsx +1 -2
- package/src/index.ts +1 -0
- package/src/logging/sendInitialLogMessages.ts +13 -9
- package/src/utils/logLibVersions.ts +1 -1
- package/src/utils/systemReport.ts +3 -3
- package/typings/generated/nrfutil/device/__mocks__/device.d.ts +1 -0
- package/typings/generated/nrfutil/device/__mocks__/device.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/batch.d.ts +3 -2
- package/typings/generated/nrfutil/device/batch.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/common.d.ts +6 -33
- package/typings/generated/nrfutil/device/common.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/device.d.ts +13 -12
- package/typings/generated/nrfutil/device/device.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/deviceInfo.d.ts +40 -0
- package/typings/generated/nrfutil/device/deviceInfo.d.ts.map +1 -0
- package/typings/generated/nrfutil/device/erase.d.ts +2 -2
- package/typings/generated/nrfutil/device/erase.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/firmwareRead.d.ts +2 -2
- package/typings/generated/nrfutil/device/firmwareRead.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/getCoreInfo.d.ts +2 -2
- package/typings/generated/nrfutil/device/getCoreInfo.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/getFwInfo.d.ts +2 -2
- package/typings/generated/nrfutil/device/getFwInfo.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/getProtectionStatus.d.ts +2 -2
- package/typings/generated/nrfutil/device/getProtectionStatus.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/list.d.ts +3 -3
- package/typings/generated/nrfutil/device/list.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/program.d.ts +2 -2
- package/typings/generated/nrfutil/device/program.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/recover.d.ts +2 -2
- package/typings/generated/nrfutil/device/recover.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/reset.d.ts +2 -2
- package/typings/generated/nrfutil/device/reset.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/setMcuState.d.ts +2 -2
- package/typings/generated/nrfutil/device/setMcuState.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/setProtectionStatus.d.ts +2 -2
- package/typings/generated/nrfutil/device/setProtectionStatus.d.ts.map +1 -1
- package/typings/generated/nrfutil/index.d.ts +2 -1
- package/typings/generated/nrfutil/index.d.ts.map +1 -1
- package/typings/generated/nrfutil/moduleVersion.d.ts +4 -0
- package/typings/generated/nrfutil/moduleVersion.d.ts.map +1 -1
- package/typings/generated/nrfutil/sandboxTypes.d.ts +9 -0
- package/typings/generated/nrfutil/sandboxTypes.d.ts.map +1 -1
- package/typings/generated/src/About/DeviceCard.d.ts.map +1 -1
- package/typings/generated/src/Device/DeviceSelector/BasicDeviceInfo.d.ts.map +1 -1
- package/typings/generated/src/Device/DeviceSelector/DeviceList/Device.d.ts +0 -1
- package/typings/generated/src/Device/DeviceSelector/DeviceList/Device.d.ts.map +1 -1
- package/typings/generated/src/Device/DeviceSelector/DeviceList/DeviceList.d.ts.map +1 -1
- package/typings/generated/src/Device/DeviceSelector/DeviceList/EditDeviceButtons.d.ts.map +1 -1
- package/typings/generated/src/Device/DeviceSelector/DeviceList/MoreDeviceInfo.d.ts +0 -1
- package/typings/generated/src/Device/DeviceSelector/DeviceList/MoreDeviceInfo.d.ts.map +1 -1
- package/typings/generated/src/Device/DeviceSelector/DeviceSelector.d.ts.map +1 -1
- package/typings/generated/src/Device/DeviceSelector/Favorite.d.ts +0 -1
- package/typings/generated/src/Device/DeviceSelector/Favorite.d.ts.map +1 -1
- package/typings/generated/src/Device/deviceLister.d.ts +1 -15
- package/typings/generated/src/Device/deviceLister.d.ts.map +1 -1
- package/typings/generated/src/Device/deviceSetup.d.ts +6 -5
- package/typings/generated/src/Device/deviceSetup.d.ts.map +1 -1
- package/typings/generated/src/Device/deviceSlice.d.ts +12 -15
- package/typings/generated/src/Device/deviceSlice.d.ts.map +1 -1
- package/typings/generated/src/Device/jprogOperations.d.ts.map +1 -1
- package/typings/generated/src/Device/sdfuOperations.d.ts.map +1 -1
- package/typings/generated/src/InlineInput/NumberInlineInput.d.ts +1 -1
- package/typings/generated/src/InlineInput/NumberInlineInput.d.ts.map +1 -1
- package/typings/generated/src/InlineInput/NumberInputWithDropdown.d.ts.map +1 -1
- package/typings/generated/src/index.d.ts +1 -1
- package/typings/generated/src/index.d.ts.map +1 -1
- package/typings/generated/src/logging/sendInitialLogMessages.d.ts.map +1 -1
- package/typings/generated/src/utils/systemReport.d.ts +1 -1
- package/typings/generated/src/utils/systemReport.d.ts.map +1 -1
- package/src/Device/DeviceSelector/DeviceList/device.scss +0 -28
- package/src/Device/DeviceSelector/DeviceList/more-device-info.scss +0 -33
- package/src/Device/DeviceSelector/favorite.scss +0 -17
|
@@ -28,13 +28,15 @@ interface Props {
|
|
|
28
28
|
const DeviceName = ({ device, inputRef, messageType }: Props) => {
|
|
29
29
|
const dispatch = useDispatch();
|
|
30
30
|
const setOrResetNickname = (name: string) => {
|
|
31
|
+
if (!device.serialNumber) return;
|
|
32
|
+
|
|
31
33
|
const newNameIsEqualToDefaultName =
|
|
32
34
|
name === displayedDeviceName(device, { respectNickname: false });
|
|
33
35
|
|
|
34
36
|
if (newNameIsEqualToDefaultName) {
|
|
35
|
-
dispatch(resetDeviceNickname(device
|
|
37
|
+
dispatch(resetDeviceNickname(device));
|
|
36
38
|
} else {
|
|
37
|
-
dispatch(setDeviceNickname(device
|
|
39
|
+
dispatch(setDeviceNickname(device, name));
|
|
38
40
|
}
|
|
39
41
|
};
|
|
40
42
|
|
|
@@ -79,7 +81,9 @@ export default ({
|
|
|
79
81
|
const autoReselectDevice = useSelector(getAutoReselectDevice);
|
|
80
82
|
const waitingToAutoReselect = useSelector(getWaitingToAutoReselect);
|
|
81
83
|
const waitingForDevice = useSelector(getWaitingForDeviceTimeout);
|
|
82
|
-
const thisDevice =
|
|
84
|
+
const thisDevice =
|
|
85
|
+
device.serialNumber &&
|
|
86
|
+
device.serialNumber === autoReselectDevice?.serialNumber;
|
|
83
87
|
|
|
84
88
|
useEffect(() => {
|
|
85
89
|
if (!showWaitingStatus) {
|
|
@@ -99,9 +103,9 @@ export default ({
|
|
|
99
103
|
]);
|
|
100
104
|
|
|
101
105
|
return (
|
|
102
|
-
<div className="basic-device-info">
|
|
106
|
+
<div className="basic-device-info tw-h-[42px]">
|
|
103
107
|
<DeviceIcon device={device} />
|
|
104
|
-
<div className="details">
|
|
108
|
+
<div className="details tw-flex tw-flex-col">
|
|
105
109
|
<DeviceName
|
|
106
110
|
device={device}
|
|
107
111
|
inputRef={deviceNameInputRef}
|
|
@@ -109,7 +113,9 @@ export default ({
|
|
|
109
113
|
/>
|
|
110
114
|
<DeviceSerialNumber device={device} />
|
|
111
115
|
</div>
|
|
112
|
-
<div className="
|
|
116
|
+
<div className="tw-mr-2.5 tw-flex tw-h-full tw-w-11 tw-flex-col tw-items-center tw-justify-center">
|
|
117
|
+
{toggles}
|
|
118
|
+
</div>
|
|
113
119
|
</div>
|
|
114
120
|
);
|
|
115
121
|
};
|
|
@@ -14,8 +14,6 @@ import { FavoriteIndicator } from '../Favorite';
|
|
|
14
14
|
import EditDeviceButtons from './EditDeviceButtons';
|
|
15
15
|
import MoreDeviceInfo from './MoreDeviceInfo';
|
|
16
16
|
|
|
17
|
-
import './device.scss';
|
|
18
|
-
|
|
19
17
|
const ShowMoreInfo = ({
|
|
20
18
|
isVisible,
|
|
21
19
|
toggleVisible,
|
|
@@ -24,7 +22,10 @@ const ShowMoreInfo = ({
|
|
|
24
22
|
toggleVisible: () => void;
|
|
25
23
|
}) => (
|
|
26
24
|
<PseudoButton
|
|
27
|
-
className={
|
|
25
|
+
className={classNames(
|
|
26
|
+
isVisible ? 'tw-visible' : 'tw-invisible group-hover:tw-visible',
|
|
27
|
+
`mdi mdi-chevron-${isVisible ? 'up' : 'down'}`
|
|
28
|
+
)}
|
|
28
29
|
testId="show-more-device-info"
|
|
29
30
|
onClick={toggleVisible}
|
|
30
31
|
/>
|
|
@@ -52,8 +53,9 @@ export default ({ device, doSelectDevice, allowMoreInfoVisible }: Props) => {
|
|
|
52
53
|
return (
|
|
53
54
|
<PseudoButton
|
|
54
55
|
className={classNames(
|
|
55
|
-
'
|
|
56
|
-
moreVisible && '
|
|
56
|
+
'tw-flex tw-flex-col tw-gap-2 tw-py-3 tw-font-light group-hover:tw-bg-white',
|
|
57
|
+
moreVisible && 'tw-bg-white',
|
|
58
|
+
moreVisible && device.serialNumber && 'tw-pb-0'
|
|
57
59
|
)}
|
|
58
60
|
onClick={() => doSelectDevice(device, false)}
|
|
59
61
|
>
|
|
@@ -11,7 +11,11 @@ import { Toggle } from '../../../Toggle/Toggle';
|
|
|
11
11
|
import classNames from '../../../utils/classNames';
|
|
12
12
|
import { getAutoReselect, setAutoReselect } from '../../deviceAutoSelectSlice';
|
|
13
13
|
import { displayedDeviceName } from '../../deviceInfo/deviceInfo';
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
Device as DeviceProps,
|
|
16
|
+
getDevices,
|
|
17
|
+
selectedDevice,
|
|
18
|
+
} from '../../deviceSlice';
|
|
15
19
|
import { AnimatedItem, AnimatedList } from './AnimatedList';
|
|
16
20
|
import BrokenDevice from './BrokenDevice';
|
|
17
21
|
import Device from './Device';
|
|
@@ -40,7 +44,7 @@ const showAllDevices = () => true;
|
|
|
40
44
|
|
|
41
45
|
const sorted = (devices: DeviceProps[]) =>
|
|
42
46
|
[...devices].sort((a, b) => {
|
|
43
|
-
if (a.favorite !== b.favorite) {
|
|
47
|
+
if (!!a.favorite !== !!b.favorite) {
|
|
44
48
|
return a.favorite ? -1 : 1;
|
|
45
49
|
}
|
|
46
50
|
|
|
@@ -60,6 +64,7 @@ const DeviceList: FC<Props> = ({
|
|
|
60
64
|
const dispatch = useDispatch();
|
|
61
65
|
const autoReconnect = useSelector(getAutoReselect);
|
|
62
66
|
const devices = useSelector(getDevices);
|
|
67
|
+
const currentDevice = useSelector(selectedDevice);
|
|
63
68
|
|
|
64
69
|
const sortedDevices = useMemo(
|
|
65
70
|
() => sorted([...devices.values()]),
|
|
@@ -71,13 +76,26 @@ const DeviceList: FC<Props> = ({
|
|
|
71
76
|
[deviceFilter, sortedDevices]
|
|
72
77
|
);
|
|
73
78
|
|
|
79
|
+
const canUseAutoReconnect =
|
|
80
|
+
(!!currentDevice && !!currentDevice?.serialNumber) || !currentDevice;
|
|
81
|
+
|
|
74
82
|
return (
|
|
75
83
|
<div className={classNames('device-list', isVisible || 'hidden')}>
|
|
76
84
|
<div className="global-auto-reconnect">
|
|
77
85
|
<Toggle
|
|
78
86
|
id="toggle-global-auto-reconnect"
|
|
79
87
|
label="Auto Reconnect"
|
|
80
|
-
|
|
88
|
+
title={
|
|
89
|
+
!canUseAutoReconnect
|
|
90
|
+
? 'Cannot auto reconnect to a device with no serial number'
|
|
91
|
+
: ''
|
|
92
|
+
}
|
|
93
|
+
disabled={!canUseAutoReconnect}
|
|
94
|
+
isToggled={
|
|
95
|
+
autoReconnect &&
|
|
96
|
+
((!!currentDevice && !!currentDevice?.serialNumber) ||
|
|
97
|
+
!currentDevice)
|
|
98
|
+
}
|
|
81
99
|
onToggle={value => {
|
|
82
100
|
dispatch(setAutoReselect(value));
|
|
83
101
|
}}
|
|
@@ -90,8 +108,8 @@ const DeviceList: FC<Props> = ({
|
|
|
90
108
|
<AnimatedList devices={sortedDevices}>
|
|
91
109
|
{filteredDevices.map(device => (
|
|
92
110
|
<AnimatedItem
|
|
93
|
-
key={device.
|
|
94
|
-
itemKey={device.
|
|
111
|
+
key={device.id.toString()}
|
|
112
|
+
itemKey={device.id.toString()}
|
|
95
113
|
>
|
|
96
114
|
{device.traits.broken ? (
|
|
97
115
|
<BrokenDevice device={device} />
|
|
@@ -18,11 +18,12 @@ interface Props {
|
|
|
18
18
|
startEditingDeviceName: () => void;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
const EditDeviceButtons: FC<Props> = ({ device, startEditingDeviceName }) =>
|
|
22
|
-
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
const EditDeviceButtons: FC<Props> = ({ device, startEditingDeviceName }) =>
|
|
22
|
+
device.serialNumber ? (
|
|
23
|
+
<ButtonGroup className="edit-device-buttons">
|
|
24
|
+
<MakeDeviceFavorite device={device} />
|
|
25
|
+
<RenameDevice startEditingDeviceName={startEditingDeviceName} />
|
|
26
|
+
</ButtonGroup>
|
|
27
|
+
) : null;
|
|
27
28
|
|
|
28
29
|
export default EditDeviceButtons;
|
|
@@ -10,56 +10,52 @@ import { SerialPort } from '../../../../nrfutil/device/common';
|
|
|
10
10
|
import { displayedDeviceName } from '../../deviceInfo/deviceInfo';
|
|
11
11
|
import { Device } from '../../deviceSlice';
|
|
12
12
|
|
|
13
|
-
import './more-device-info.scss';
|
|
14
|
-
|
|
15
13
|
const Row = ({ children }: { children: ReactNode }) => (
|
|
16
|
-
<div className="
|
|
17
|
-
<div className="
|
|
14
|
+
<div className=" tw-flex tw-flex-row tw-pr-5">
|
|
15
|
+
<div className=" tw-w-[68px]" />
|
|
18
16
|
{children}
|
|
19
17
|
</div>
|
|
20
18
|
);
|
|
21
19
|
|
|
22
20
|
const PcaNumber = ({ device }: { device: Device }) => {
|
|
23
|
-
if (!device.
|
|
21
|
+
if (!device.devkit?.boardVersion) {
|
|
24
22
|
return null;
|
|
25
23
|
}
|
|
26
24
|
|
|
27
|
-
return
|
|
25
|
+
return (
|
|
26
|
+
<Row>
|
|
27
|
+
<div>{device.devkit.boardVersion}</div>
|
|
28
|
+
</Row>
|
|
29
|
+
);
|
|
28
30
|
};
|
|
29
31
|
|
|
30
32
|
const MaybeDeviceName = ({ device }: { device: Device }) => {
|
|
31
|
-
|
|
32
|
-
if (!hasNickname) {
|
|
33
|
+
if (!device.nickname) {
|
|
33
34
|
return null;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
return (
|
|
37
|
-
<
|
|
38
|
-
{displayedDeviceName(device, { respectNickname: false })}
|
|
39
|
-
</
|
|
38
|
+
<Row>
|
|
39
|
+
<div>{displayedDeviceName(device, { respectNickname: false })}</div>
|
|
40
|
+
</Row>
|
|
40
41
|
);
|
|
41
42
|
};
|
|
42
43
|
|
|
43
|
-
const Serialports = ({ ports }: { ports: SerialPort[] }) =>
|
|
44
|
-
|
|
45
|
-
{ports.map(port => (
|
|
46
|
-
<li key={port.path}>{port.comName}</li>
|
|
47
|
-
))}
|
|
48
|
-
</ul>
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
export default ({ device }: { device: Device }) => (
|
|
52
|
-
<div className="more-infos">
|
|
44
|
+
const Serialports = ({ ports }: { ports: SerialPort[] }) =>
|
|
45
|
+
ports.length > 0 ? (
|
|
53
46
|
<Row>
|
|
54
|
-
<
|
|
47
|
+
<ul className="tw-text-center tw-underline">
|
|
48
|
+
{ports.map(port => (
|
|
49
|
+
<li key={port.path}>{port.comName}</li>
|
|
50
|
+
))}
|
|
51
|
+
</ul>
|
|
55
52
|
</Row>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
)}
|
|
53
|
+
) : null;
|
|
54
|
+
|
|
55
|
+
export default ({ device }: { device: Device }) => (
|
|
56
|
+
<div className="tw-preflight tw-flex tw-flex-col tw-gap-2">
|
|
57
|
+
<PcaNumber device={device} />
|
|
58
|
+
<MaybeDeviceName device={device} />
|
|
59
|
+
<Serialports ports={device.serialPorts ?? []} />
|
|
64
60
|
</div>
|
|
65
61
|
);
|
|
@@ -14,18 +14,13 @@ import DeviceSelector from './DeviceSelector';
|
|
|
14
14
|
|
|
15
15
|
jest.mock('../../../nrfutil/device/device');
|
|
16
16
|
|
|
17
|
+
const DEVICE_SERIAL_NUMBER = '000000001';
|
|
18
|
+
|
|
17
19
|
const testDevice: Device = {
|
|
18
20
|
id: 1,
|
|
19
|
-
hwInfo: {
|
|
20
|
-
romSize: 123,
|
|
21
|
-
ramSize: 456,
|
|
22
|
-
romPageSize: 789,
|
|
23
|
-
deviceFamily: 'PCATest',
|
|
24
|
-
deviceVersion: 'PCATest',
|
|
25
|
-
},
|
|
26
21
|
broken: null,
|
|
27
22
|
usb: {
|
|
28
|
-
serialNumber:
|
|
23
|
+
serialNumber: DEVICE_SERIAL_NUMBER,
|
|
29
24
|
manufacturer: 'testManufacturer',
|
|
30
25
|
product: 'testProduct',
|
|
31
26
|
osDevicePath: '/some-path',
|
|
@@ -66,26 +61,13 @@ const testDevice: Device = {
|
|
|
66
61
|
vcom: 2,
|
|
67
62
|
},
|
|
68
63
|
],
|
|
69
|
-
boardVersion: 'PCATest',
|
|
70
|
-
serialport: {
|
|
71
|
-
path: 'COM1',
|
|
72
|
-
manufacturer: 'testManufacturer',
|
|
73
|
-
productId: 'testProduct',
|
|
74
|
-
serialNumber: '000000001',
|
|
75
|
-
vendorId: 'testVendor',
|
|
76
|
-
comName: 'COM1',
|
|
77
|
-
vcom: 0,
|
|
78
|
-
},
|
|
79
64
|
favorite: false,
|
|
80
65
|
traits: {
|
|
81
66
|
jlink: true,
|
|
82
67
|
},
|
|
83
|
-
|
|
68
|
+
devkit: {
|
|
84
69
|
boardVersion: 'PCATest',
|
|
85
|
-
serialNumber: 'PCATest',
|
|
86
|
-
jlinkObFirmwareVersion: 'PCATest',
|
|
87
70
|
deviceFamily: 'PCATest',
|
|
88
|
-
deviceVersion: 'PCATest',
|
|
89
71
|
},
|
|
90
72
|
};
|
|
91
73
|
|
|
@@ -151,7 +133,7 @@ describe('DeviceSelector', () => {
|
|
|
151
133
|
/>,
|
|
152
134
|
[addDevice(testDevice)]
|
|
153
135
|
);
|
|
154
|
-
expect(screen.getByText(
|
|
136
|
+
expect(screen.getByText(DEVICE_SERIAL_NUMBER)).toBeInTheDocument();
|
|
155
137
|
});
|
|
156
138
|
|
|
157
139
|
it('should unlist disconnected devices', () => {
|
|
@@ -166,7 +148,7 @@ describe('DeviceSelector', () => {
|
|
|
166
148
|
/>,
|
|
167
149
|
[addDevice(testDevice), removeDevice(testDevice)]
|
|
168
150
|
);
|
|
169
|
-
expect(screen.queryByText(
|
|
151
|
+
expect(screen.queryByText(DEVICE_SERIAL_NUMBER)).toBeNull();
|
|
170
152
|
});
|
|
171
153
|
|
|
172
154
|
it('should show more device info when selecting the expand button', () => {
|
|
@@ -200,8 +182,8 @@ describe('DeviceSelector', () => {
|
|
|
200
182
|
);
|
|
201
183
|
|
|
202
184
|
fireEvent.click(screen.getByText('Select device'));
|
|
203
|
-
fireEvent.click(screen.getByText(
|
|
204
|
-
expect(screen.getAllByText(
|
|
185
|
+
fireEvent.click(screen.getByText(DEVICE_SERIAL_NUMBER));
|
|
186
|
+
expect(screen.getAllByText(DEVICE_SERIAL_NUMBER)).toHaveLength(2);
|
|
205
187
|
});
|
|
206
188
|
|
|
207
189
|
it('can deselect selected devices', async () => {
|
|
@@ -217,10 +199,10 @@ describe('DeviceSelector', () => {
|
|
|
217
199
|
[addDevice(testDevice)]
|
|
218
200
|
);
|
|
219
201
|
fireEvent.click(screen.getByText('Select device'));
|
|
220
|
-
fireEvent.click(screen.getByText(
|
|
202
|
+
fireEvent.click(screen.getByText(DEVICE_SERIAL_NUMBER));
|
|
221
203
|
await screen.findByTestId('disconnect-device');
|
|
222
204
|
fireEvent.click(screen.getByTestId('disconnect-device'));
|
|
223
|
-
expect(screen.getAllByText(
|
|
205
|
+
expect(screen.getAllByText(DEVICE_SERIAL_NUMBER)).toHaveLength(1);
|
|
224
206
|
expect(screen.getByText('Select device')).toBeInTheDocument();
|
|
225
207
|
});
|
|
226
208
|
|
|
@@ -250,10 +232,10 @@ describe('DeviceSelector', () => {
|
|
|
250
232
|
[addDevice(testDevice)]
|
|
251
233
|
);
|
|
252
234
|
fireEvent.click(screen.getByText('Select device'));
|
|
253
|
-
fireEvent.click(screen.getByText(
|
|
235
|
+
fireEvent.click(screen.getByText(DEVICE_SERIAL_NUMBER));
|
|
254
236
|
|
|
255
237
|
expect(screen.queryByText('OK')).toBeNull();
|
|
256
|
-
expect(screen.getAllByText(
|
|
238
|
+
expect(screen.getAllByText(DEVICE_SERIAL_NUMBER)).toHaveLength(2);
|
|
257
239
|
});
|
|
258
240
|
|
|
259
241
|
it('should deselect device when custom devices are disabled and no valid firmware is defined', async () => {
|
|
@@ -283,13 +265,11 @@ describe('DeviceSelector', () => {
|
|
|
283
265
|
);
|
|
284
266
|
|
|
285
267
|
fireEvent.click(screen.getByText('Select device'));
|
|
286
|
-
fireEvent.click(screen.getByText(
|
|
268
|
+
fireEvent.click(screen.getByText(DEVICE_SERIAL_NUMBER));
|
|
287
269
|
|
|
288
270
|
expect(screen.queryByText('OK')).toBeNull();
|
|
289
271
|
await waitFor(() => {
|
|
290
|
-
expect(screen.getAllByText(
|
|
291
|
-
1
|
|
292
|
-
);
|
|
272
|
+
expect(screen.getAllByText(DEVICE_SERIAL_NUMBER)).toHaveLength(1);
|
|
293
273
|
});
|
|
294
274
|
await screen.findByText('Select device');
|
|
295
275
|
});
|
|
@@ -309,7 +289,7 @@ describe('DeviceSelector', () => {
|
|
|
309
289
|
);
|
|
310
290
|
|
|
311
291
|
fireEvent.click(screen.getByText('Select device'));
|
|
312
|
-
fireEvent.click(screen.getByText(
|
|
292
|
+
fireEvent.click(screen.getByText(DEVICE_SERIAL_NUMBER));
|
|
313
293
|
|
|
314
294
|
await screen.findByText(
|
|
315
295
|
'Device must be programmed, do you want to proceed?'
|
|
@@ -331,7 +311,7 @@ describe('DeviceSelector', () => {
|
|
|
331
311
|
);
|
|
332
312
|
|
|
333
313
|
fireEvent.click(screen.getByText('Select device'));
|
|
334
|
-
fireEvent.click(screen.getByText(
|
|
314
|
+
fireEvent.click(screen.getByText(DEVICE_SERIAL_NUMBER));
|
|
335
315
|
|
|
336
316
|
await screen.findByText(
|
|
337
317
|
'Device must be programmed, do you want to proceed?'
|
|
@@ -345,6 +325,6 @@ describe('DeviceSelector', () => {
|
|
|
345
325
|
)
|
|
346
326
|
).toBeNull();
|
|
347
327
|
|
|
348
|
-
expect(screen.getAllByText(
|
|
328
|
+
expect(screen.getAllByText(DEVICE_SERIAL_NUMBER)).toHaveLength(2);
|
|
349
329
|
});
|
|
350
330
|
});
|
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
* SPDX-License-Identifier: LicenseRef-Nordic-4-Clause
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import React, { useCallback, useEffect, useState } from 'react';
|
|
7
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
8
8
|
import { useDispatch, useSelector } from 'react-redux';
|
|
9
9
|
|
|
10
|
+
import { NrfutilDeviceLib } from '../../../nrfutil';
|
|
10
11
|
import { DeviceTraits } from '../../../nrfutil/device/common';
|
|
12
|
+
import logger from '../../logging';
|
|
11
13
|
import useHotKey from '../../utils/useHotKey';
|
|
12
14
|
import {
|
|
13
15
|
clearWaitForDevice,
|
|
@@ -22,7 +24,8 @@ import {
|
|
|
22
24
|
Device,
|
|
23
25
|
deviceIsSelected as deviceIsSelectedSelector,
|
|
24
26
|
selectDevice,
|
|
25
|
-
|
|
27
|
+
selectedDevice,
|
|
28
|
+
setSelectedDeviceInfo,
|
|
26
29
|
} from '../deviceSlice';
|
|
27
30
|
import DeviceList from './DeviceList/DeviceList';
|
|
28
31
|
import SelectDevice from './SelectDevice';
|
|
@@ -54,7 +57,7 @@ export default ({
|
|
|
54
57
|
const [deviceListVisible, setDeviceListVisible] = useState(false);
|
|
55
58
|
|
|
56
59
|
const deviceIsSelected = useSelector(deviceIsSelectedSelector);
|
|
57
|
-
const
|
|
60
|
+
const currentDevice = useSelector(selectedDevice);
|
|
58
61
|
const waitingToAutoReconnect = useSelector(getWaitingToAutoReselect);
|
|
59
62
|
const showSelectedDevice = deviceIsSelected || waitingToAutoReconnect;
|
|
60
63
|
|
|
@@ -65,25 +68,47 @@ export default ({
|
|
|
65
68
|
dispatch(deselectDevice());
|
|
66
69
|
}, [dispatch, onDeviceDeselected]);
|
|
67
70
|
|
|
71
|
+
const abortController = useRef<AbortController>();
|
|
72
|
+
|
|
68
73
|
// Ensure that useCallback is
|
|
69
74
|
// not updated frequently as this
|
|
70
75
|
// will have a side effect to stop and start the hotplug events
|
|
71
76
|
const doSelectDevice = useCallback(
|
|
72
|
-
(device: Device, autoReselected: boolean) => {
|
|
77
|
+
async (device: Device, autoReselected: boolean) => {
|
|
73
78
|
dispatch(clearWaitForDevice());
|
|
74
79
|
setDeviceListVisible(false);
|
|
75
80
|
dispatch(selectDevice(device));
|
|
76
81
|
dispatch(setAutoSelectDevice(device));
|
|
77
82
|
onDeviceSelected(device, autoReselected);
|
|
83
|
+
|
|
84
|
+
abortController.current?.abort();
|
|
85
|
+
abortController.current = new AbortController();
|
|
86
|
+
const deviceInfo = await NrfutilDeviceLib.deviceInfo(
|
|
87
|
+
device,
|
|
88
|
+
undefined,
|
|
89
|
+
undefined,
|
|
90
|
+
abortController.current
|
|
91
|
+
);
|
|
92
|
+
abortController.current = undefined;
|
|
93
|
+
setSelectedDeviceInfo(deviceInfo);
|
|
94
|
+
|
|
78
95
|
if (deviceSetupConfig) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
96
|
+
if (device.serialNumber) {
|
|
97
|
+
dispatch(
|
|
98
|
+
setupDevice(
|
|
99
|
+
device,
|
|
100
|
+
deviceSetupConfig,
|
|
101
|
+
onDeviceIsReady,
|
|
102
|
+
doDeselectDevice,
|
|
103
|
+
deviceInfo
|
|
104
|
+
)
|
|
105
|
+
);
|
|
106
|
+
} else {
|
|
107
|
+
logger.warn(
|
|
108
|
+
`Selected device has no serial number. Device setup is not supported`
|
|
109
|
+
);
|
|
110
|
+
onDeviceIsReady(device);
|
|
111
|
+
}
|
|
87
112
|
}
|
|
88
113
|
},
|
|
89
114
|
[
|
|
@@ -145,7 +170,7 @@ export default ({
|
|
|
145
170
|
<DeviceList
|
|
146
171
|
isVisible={deviceListVisible}
|
|
147
172
|
doSelectDevice={(device, autoReselected) => {
|
|
148
|
-
if (device.
|
|
173
|
+
if (device.id === currentDevice?.id) {
|
|
149
174
|
setDeviceListVisible(false);
|
|
150
175
|
return;
|
|
151
176
|
}
|
|
@@ -8,19 +8,18 @@ import React, { FC } from 'react';
|
|
|
8
8
|
import { useDispatch } from 'react-redux';
|
|
9
9
|
|
|
10
10
|
import PseudoButton from '../../PseudoButton/PseudoButton';
|
|
11
|
+
import classNames from '../../utils/classNames';
|
|
11
12
|
import { Device, toggleDeviceFavorited } from '../deviceSlice';
|
|
12
13
|
|
|
13
|
-
import './favorite.scss';
|
|
14
|
-
|
|
15
14
|
export const MakeDeviceFavorite: FC<{ device: Device }> = ({ device }) => {
|
|
16
15
|
const dispatch = useDispatch();
|
|
17
16
|
|
|
18
17
|
const toggleFavorite = () => {
|
|
19
|
-
dispatch(toggleDeviceFavorited(device
|
|
18
|
+
dispatch(toggleDeviceFavorited(device));
|
|
20
19
|
};
|
|
21
20
|
|
|
22
21
|
return (
|
|
23
|
-
<PseudoButton className="
|
|
22
|
+
<PseudoButton className="tw-mr-[1ex]" onClick={toggleFavorite}>
|
|
24
23
|
<span
|
|
25
24
|
className={`mdi star ${
|
|
26
25
|
device.favorite ? 'mdi-star-off' : 'mdi-star'
|
|
@@ -35,15 +34,16 @@ export const FavoriteIndicator: FC<{ device: Device }> = ({ device }) => {
|
|
|
35
34
|
const dispatch = useDispatch();
|
|
36
35
|
|
|
37
36
|
const toggleFavorite = () => {
|
|
38
|
-
dispatch(toggleDeviceFavorited(device
|
|
37
|
+
dispatch(toggleDeviceFavorited(device));
|
|
39
38
|
};
|
|
40
39
|
|
|
41
|
-
return (
|
|
40
|
+
return device.serialNumber ? (
|
|
42
41
|
<PseudoButton
|
|
43
|
-
className={
|
|
44
|
-
device.favorite
|
|
45
|
-
|
|
42
|
+
className={classNames(
|
|
43
|
+
!device.favorite && 'tw-invisible group-hover:tw-visible',
|
|
44
|
+
`mdi ${device.favorite ? 'mdi-star' : 'mdi-star-outline'}`
|
|
45
|
+
)}
|
|
46
46
|
onClick={toggleFavorite}
|
|
47
47
|
/>
|
|
48
|
-
);
|
|
48
|
+
) : null;
|
|
49
49
|
};
|
|
@@ -16,9 +16,6 @@
|
|
|
16
16
|
.details {
|
|
17
17
|
width: inherit;
|
|
18
18
|
|
|
19
|
-
display: flex;
|
|
20
|
-
flex-direction: column;
|
|
21
|
-
|
|
22
19
|
line-height: 1;
|
|
23
20
|
|
|
24
21
|
.name {
|
|
@@ -49,14 +46,5 @@
|
|
|
49
46
|
text-overflow: ellipsis;
|
|
50
47
|
}
|
|
51
48
|
}
|
|
52
|
-
|
|
53
|
-
.toggles {
|
|
54
|
-
display: flex;
|
|
55
|
-
flex-direction: column;
|
|
56
|
-
align-items: center;
|
|
57
|
-
|
|
58
|
-
width: 44px;
|
|
59
|
-
margin-right: 10px;
|
|
60
|
-
}
|
|
61
49
|
}
|
|
62
50
|
}
|
|
@@ -199,7 +199,7 @@ const devicesByPca: { [P in KnownDevicePCA]: DeviceInfo } = {
|
|
|
199
199
|
|
|
200
200
|
const deviceByPca = (device: Device) =>
|
|
201
201
|
devicesByPca[
|
|
202
|
-
String(device.
|
|
202
|
+
String(device.devkit?.boardVersion).toUpperCase() as KnownDevicePCA
|
|
203
203
|
];
|
|
204
204
|
|
|
205
205
|
const NORDIC_VENDOR_ID = '1915';
|
|
@@ -252,7 +252,7 @@ export const displayedDeviceName = (
|
|
|
252
252
|
return device.nickname;
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
return deviceInfo(device).name || device.
|
|
255
|
+
return deviceInfo(device).name || device.devkit?.boardVersion || 'Unknown';
|
|
256
256
|
};
|
|
257
257
|
|
|
258
258
|
export const productPageUrl = (device: Device) =>
|