Skip to content

Commit e50020c

Browse files
committed
fix board select component
1 parent 84749c5 commit e50020c

File tree

5 files changed

+198
-434
lines changed

5 files changed

+198
-434
lines changed

arduino-ide-extension/src/browser/dialogs/certificate-uploader/certificate-uploader-component.tsx

Lines changed: 19 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
import * as React from 'react';
2-
import {
3-
AvailableBoard,
4-
BoardsServiceProvider,
5-
} from '../../boards/boards-service-provider';
6-
import { ArduinoSelect } from '../../widgets/arduino-select';
2+
import { AvailableBoard } from '../../boards/boards-service-provider';
73
import { CertificateListComponent } from './certificate-list';
4+
import { SelectBoardComponent } from './select-board-components';
85

96
export const CertificateUploaderComponent = ({
10-
boardsServiceClient,
7+
availableBoards,
118
certificates,
129
// addCertificate,
10+
updatableFqbns,
1311
uploadCertificates,
1412
openContextMenu,
1513
}: {
16-
boardsServiceClient: BoardsServiceProvider;
14+
availableBoards: AvailableBoard[];
1715
certificates: string[];
1816
addCertificate: (cert: string) => void;
17+
updatableFqbns: string[];
1918
uploadCertificates: (
2019
fqbn: string,
2120
address: string,
@@ -29,64 +28,20 @@ export const CertificateUploaderComponent = ({
2928

3029
const [selectedCerts, setSelectedCerts] = React.useState<string[]>([]);
3130

32-
const [selectedBoard, setSelectedBoard] = React.useState<{
33-
label: string;
34-
value: AvailableBoard;
35-
} | null>(null);
36-
37-
const [selectBoardPlaceholder, setSelectBoardPlaceholder] =
38-
React.useState('');
39-
const [availableBoards, setAvailableBoards] = React.useState<
40-
{
41-
label: string;
42-
value: AvailableBoard;
43-
}[]
44-
>([]);
45-
46-
React.useEffect(() => {
47-
boardsServiceClient.onAvailableBoardsChanged((availableBoards) => {
48-
let placeholderTxt = 'Select a board...';
49-
let selectedBoard = -1;
50-
const boardsList = availableBoards
51-
.filter(
52-
(board) =>
53-
!!board.fqbn && board.state === AvailableBoard.State.recognized
54-
)
55-
.map((board, i) => {
56-
if (board.selected) {
57-
selectedBoard = i;
58-
}
59-
return {
60-
label: `${board.name} at ${board.port?.address}`,
61-
value: board,
62-
};
63-
});
64-
65-
if (boardsList.length === 0) {
66-
placeholderTxt = 'No board connected to serial port';
67-
}
68-
69-
setSelectBoardPlaceholder(placeholderTxt);
70-
setAvailableBoards(boardsList);
71-
setSelectedBoard(boardsList[selectedBoard] || null);
72-
});
73-
}, [boardsServiceClient]);
31+
const [selectedBoard, setSelectedBoard] =
32+
React.useState<AvailableBoard | null>(null);
7433

7534
const installCertificates = async () => {
76-
if (
77-
!selectedBoard?.value ||
78-
!selectedBoard.value.fqbn ||
79-
!selectedBoard.value.port
80-
) {
35+
if (!selectedBoard || !selectedBoard.fqbn || !selectedBoard.port) {
8136
return;
8237
}
8338

8439
setInstallFeedback('installing');
8540

8641
try {
8742
await uploadCertificates(
88-
selectedBoard.value.fqbn,
89-
selectedBoard.value.port.address,
43+
selectedBoard.fqbn,
44+
selectedBoard.port.address,
9045
selectedCerts
9146
);
9247
setInstallFeedback('ok');
@@ -119,31 +74,23 @@ export const CertificateUploaderComponent = ({
11974
</div>
12075
<div className="dialogRow">
12176
<div className="fl1">
122-
<ArduinoSelect
123-
id="board-select"
124-
menuPosition="fixed"
125-
isDisabled={availableBoards.length === 0}
126-
placeholder={selectBoardPlaceholder}
127-
options={availableBoards}
128-
value={selectedBoard}
129-
tabSelectsValue={false}
130-
onChange={(value) => {
131-
if (value) {
77+
<SelectBoardComponent
78+
availableBoards={availableBoards}
79+
updatableFqbns={updatableFqbns}
80+
onBoardSelect={(board) => {
81+
if (board) {
13282
setInstallFeedback(null);
133-
setSelectedBoard(value);
83+
setSelectedBoard(board);
13484
}
13585
}}
86+
selectedBoard={selectedBoard}
13687
/>
13788
</div>
13889
<button
13990
type="button"
14091
className="theia-button primary"
14192
onClick={installCertificates}
142-
disabled={
143-
selectedCerts.length === 0 ||
144-
availableBoards.length === 0 ||
145-
!selectedBoard
146-
}
93+
disabled={selectedCerts.length === 0 || !selectedBoard}
14794
>
14895
Upload
14996
</button>

arduino-ide-extension/src/browser/dialogs/certificate-uploader/certificate-uploader-dialog.tsx

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import { AbstractDialog, DialogProps } from '@theia/core/lib/browser/dialogs';
44
import { Widget } from '@phosphor/widgets';
55
import { Message } from '@phosphor/messaging';
66
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
7-
import { BoardsServiceProvider } from '../../boards/boards-service-provider';
7+
import {
8+
AvailableBoard,
9+
BoardsServiceProvider,
10+
} from '../../boards/boards-service-provider';
811
import { CertificateUploaderComponent } from './certificate-uploader-component';
912
import { ArduinoPreferences } from '../../arduino-preferences';
1013
import {
@@ -13,6 +16,7 @@ import {
1316
} from '@theia/core/lib/browser/preferences/preference-service';
1417
import { CommandRegistry } from '@theia/core/lib/common/command';
1518
import { certificateList, sanifyCertString } from './utils';
19+
import { ArduinoFirmwareUploader } from '../../../common/protocol/arduino-firmware-uploader';
1620

1721
@injectable()
1822
export class UploadCertificateDialogWidget extends ReactWidget {
@@ -28,7 +32,12 @@ export class UploadCertificateDialogWidget extends ReactWidget {
2832
@inject(CommandRegistry)
2933
protected readonly commandRegistry: CommandRegistry;
3034

35+
@inject(ArduinoFirmwareUploader)
36+
protected readonly arduinoFirmwareUploader: ArduinoFirmwareUploader;
37+
3138
protected certificates: string[] = [];
39+
protected updatableFqbns: string[] = [];
40+
protected availableBoards: AvailableBoard[] = [];
3241

3342
constructor() {
3443
super();
@@ -50,6 +59,16 @@ export class UploadCertificateDialogWidget extends ReactWidget {
5059
this.update();
5160
}
5261
});
62+
63+
this.arduinoFirmwareUploader.updatableBoards().then((fqbns) => {
64+
this.updatableFqbns = fqbns;
65+
this.update();
66+
});
67+
68+
this.boardsServiceClient.onAvailableBoardsChanged((availableBoards) => {
69+
this.availableBoards = availableBoards;
70+
this.update();
71+
});
5372
}
5473

5574
private addCertificate(certificate: string) {
@@ -88,8 +107,9 @@ export class UploadCertificateDialogWidget extends ReactWidget {
88107
protected render(): React.ReactNode {
89108
return (
90109
<CertificateUploaderComponent
91-
boardsServiceClient={this.boardsServiceClient}
110+
availableBoards={this.availableBoards}
92111
certificates={this.certificates}
112+
updatableFqbns={this.updatableFqbns}
93113
addCertificate={this.addCertificate.bind(this)}
94114
uploadCertificates={this.uploadCertificates.bind(this)}
95115
openContextMenu={this.openContextMenu.bind(this)}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import * as React from 'react';
2+
import { AvailableBoard } from '../../boards/boards-service-provider';
3+
import { ArduinoSelect } from '../../widgets/arduino-select';
4+
5+
type BoardOption = { value: string; label: string };
6+
7+
export const SelectBoardComponent = ({
8+
availableBoards,
9+
updatableFqbns,
10+
onBoardSelect,
11+
selectedBoard,
12+
}: {
13+
availableBoards: AvailableBoard[];
14+
updatableFqbns: string[];
15+
onBoardSelect: (board: AvailableBoard | null) => void;
16+
selectedBoard: AvailableBoard | null;
17+
}): React.ReactElement => {
18+
const [selectOptions, setSelectOptions] = React.useState<BoardOption[]>([]);
19+
20+
const [selectBoardPlaceholder, setSelectBoardPlaceholder] =
21+
React.useState('');
22+
23+
const selectOption = React.useCallback(
24+
(boardOpt: BoardOption) => {
25+
onBoardSelect(
26+
(boardOpt &&
27+
availableBoards.find((board) => board.fqbn === boardOpt.value)) ||
28+
null
29+
);
30+
},
31+
[availableBoards, onBoardSelect]
32+
);
33+
34+
React.useEffect(() => {
35+
let placeholderTxt = 'Select a board...';
36+
let selBoard = -1;
37+
const updatableBoards = availableBoards.filter(
38+
(board) => board.fqbn && updatableFqbns.includes(board.fqbn)
39+
);
40+
const boardsList: BoardOption[] = updatableBoards.map((board, i) => {
41+
if (board.selected) {
42+
selBoard = i;
43+
}
44+
return {
45+
label: `${board.name} at ${board.port?.address}`,
46+
value: board.fqbn || '',
47+
};
48+
});
49+
50+
if (boardsList.length === 0) {
51+
placeholderTxt = 'No board connected to serial port';
52+
}
53+
54+
setSelectBoardPlaceholder(placeholderTxt);
55+
setSelectOptions(boardsList);
56+
57+
selectOption(boardsList[selBoard]);
58+
}, [availableBoards, onBoardSelect, selectOption, updatableFqbns]);
59+
60+
return (
61+
<ArduinoSelect
62+
id="board-select"
63+
menuPosition="fixed"
64+
isDisabled={selectOptions.length === 0}
65+
placeholder={selectBoardPlaceholder}
66+
options={selectOptions}
67+
value={
68+
(selectedBoard && {
69+
value: selectedBoard.fqbn,
70+
label: `${selectedBoard.name} at ${selectedBoard.port?.address}`,
71+
}) ||
72+
null
73+
}
74+
tabSelectsValue={false}
75+
onChange={selectOption}
76+
/>
77+
);
78+
};

0 commit comments

Comments
 (0)