Skip to content

Commit d5eaa91

Browse files
author
Akos Kitta
committed
fix: board select component
to show inferred item if any
1 parent 8ee05ba commit d5eaa91

File tree

6 files changed

+104
-86
lines changed

6 files changed

+104
-86
lines changed

arduino-ide-extension/src/browser/boards/boards-config-dialog.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
emptyBoardsConfig,
2020
PortIdentifier,
2121
} from '../../common/protocol/boards-service';
22+
import { Defined } from '../../common/types';
2223
import { NotificationCenter } from '../notification-center';
2324
import { ReactDialog } from '../theia/dialogs/dialogs';
2425
import { BoardsConfigComponent } from './boards-config-component';
@@ -39,7 +40,9 @@ export class BoardsConfigDialog extends ReactDialog<BoardsConfig> {
3940
@inject(FrontendApplicationStateService)
4041
private readonly appStateService: FrontendApplicationStateService;
4142

42-
private readonly onFilterTextDidChangeEmitter: Emitter<string>;
43+
private readonly onFilterTextDidChangeEmitter: Emitter<
44+
Defined<EditBoardsConfigActionParams['query']>
45+
>;
4346
private readonly onBoardSelected = (board: BoardIdentifier): void => {
4447
this._boardsConfig.selectedBoard = board;
4548
this.update();
@@ -92,13 +95,13 @@ export class BoardsConfigDialog extends ReactDialog<BoardsConfig> {
9295
params?: EditBoardsConfigActionParams
9396
): Promise<BoardsConfig | undefined> {
9497
if (params) {
95-
if (typeof params?.query === 'string') {
96-
this.onFilterTextDidChangeEmitter.fire(params?.query);
98+
if (params.query || typeof params.query === 'string') {
99+
this.onFilterTextDidChangeEmitter.fire(params.query);
97100
}
98-
if (params?.selectedPort) {
101+
if (params.selectedPort) {
99102
this._boardsConfig.selectedPort = params.selectedPort;
100103
}
101-
if (params?.selectedBoard) {
104+
if (params.selectedBoard) {
102105
this._boardsConfig.selectedBoard = params.selectedBoard;
103106
}
104107
}

arduino-ide-extension/src/browser/boards/boards-toolbar-item.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,6 @@ export namespace BoardsDropDown {
3535
readonly coords: BoardsDropDownListCoords | 'hidden';
3636
readonly boardList: BoardListUI;
3737
readonly openBoardsConfig: () => void;
38-
/**
39-
* Hides the board list dropdown, if it's visible. Otherwise, NOOP.
40-
*/
41-
readonly hide: () => void;
4238
}
4339
}
4440

@@ -218,7 +214,6 @@ export class BoardListDropDown extends React.Component<BoardsDropDown.Props> {
218214
event.preventDefault();
219215
event.stopPropagation();
220216
onRevert({ selectedBoard: inferredItem.board, selectedPort: port });
221-
this.props.hide();
222217
}}
223218
/>
224219
) : undefined;
@@ -312,6 +307,16 @@ export class BoardsToolBarItem extends React.Component<
312307
'fa',
313308
protocolIcon
314309
);
310+
const originalOnSelect = boardList.onSelect;
311+
boardList['onSelect'] = (params) => {
312+
this.hide();
313+
return originalOnSelect.bind(boardList)(params);
314+
};
315+
const originalOnEdit = boardList.onEdit;
316+
boardList['onEdit'] = (params) => {
317+
this.hide();
318+
return originalOnEdit.bind(boardList)(params);
319+
};
315320
return (
316321
<React.Fragment>
317322
<div
@@ -338,7 +343,6 @@ export class BoardsToolBarItem extends React.Component<
338343
openBoardsConfig={() =>
339344
boardList.onEdit({ query: { action: 'clear-if-not-empty' } })
340345
}
341-
hide={this.hide}
342346
></BoardListDropDown>
343347
</React.Fragment>
344348
);

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

Lines changed: 53 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,51 @@
1-
import * as React from '@theia/core/shared/react';
1+
import { DialogProps } from '@theia/core/lib/browser/dialogs';
2+
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
3+
import {
4+
PreferenceScope,
5+
PreferenceService,
6+
} from '@theia/core/lib/browser/preferences/preference-service';
7+
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
8+
import { CommandRegistry } from '@theia/core/lib/common/command';
9+
import { nls } from '@theia/core/lib/common/nls';
10+
import type { Message } from '@theia/core/shared/@phosphor/messaging';
11+
import { Widget } from '@theia/core/shared/@phosphor/widgets';
212
import {
313
inject,
414
injectable,
515
postConstruct,
616
} from '@theia/core/shared/inversify';
7-
import { DialogProps } from '@theia/core/lib/browser/dialogs';
8-
import { AbstractDialog } from '../../theia/dialogs/dialogs';
9-
import { Widget } from '@theia/core/shared/@phosphor/widgets';
10-
import { Message } from '@theia/core/shared/@phosphor/messaging';
11-
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
12-
import { BoardsServiceProvider } from '../../boards/boards-service-provider';
13-
// import { CertificateUploaderComponent } from './certificate-uploader-component';
14-
import { ArduinoPreferences } from '../../arduino-preferences';
15-
import { PreferenceService } from '@theia/core/lib/browser/preferences/preference-service';
16-
import { CommandRegistry } from '@theia/core/lib/common/command';
17-
import { certificateList } from './utils';
17+
import * as React from '@theia/core/shared/react';
1818
import { ArduinoFirmwareUploader } from '../../../common/protocol/arduino-firmware-uploader';
19-
import { nls } from '@theia/core/lib/common';
20-
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
19+
import { createBoardList } from '../../../common/protocol/board-list';
20+
import { ArduinoPreferences } from '../../arduino-preferences';
21+
import { BoardsServiceProvider } from '../../boards/boards-service-provider';
22+
import { AbstractDialog } from '../../theia/dialogs/dialogs';
23+
import { CertificateUploaderComponent } from './certificate-uploader-component';
24+
import { certificateList, sanifyCertString } from './utils';
2125

2226
@injectable()
2327
export class UploadCertificateDialogWidget extends ReactWidget {
2428
@inject(BoardsServiceProvider)
25-
protected readonly boardsServiceProvider: BoardsServiceProvider;
26-
29+
private readonly boardsServiceProvider: BoardsServiceProvider;
2730
@inject(ArduinoPreferences)
28-
protected readonly arduinoPreferences: ArduinoPreferences;
29-
31+
private readonly arduinoPreferences: ArduinoPreferences;
3032
@inject(PreferenceService)
31-
protected readonly preferenceService: PreferenceService;
32-
33+
private readonly preferenceService: PreferenceService;
3334
@inject(CommandRegistry)
34-
protected readonly commandRegistry: CommandRegistry;
35-
35+
private readonly commandRegistry: CommandRegistry;
3636
@inject(ArduinoFirmwareUploader)
37-
protected readonly arduinoFirmwareUploader: ArduinoFirmwareUploader;
38-
37+
private readonly arduinoFirmwareUploader: ArduinoFirmwareUploader;
3938
@inject(FrontendApplicationStateService)
4039
private readonly appStateService: FrontendApplicationStateService;
4140

42-
protected certificates: string[] = [];
43-
protected updatableFqbns: string[] = [];
44-
// protected availableBoards: AvailableBoard[] = [];
41+
private certificates: string[] = [];
42+
private updatableFqbns: string[] = [];
43+
private boardList = createBoardList({});
4544

46-
public busyCallback = (busy: boolean) => {
45+
busyCallback = (busy: boolean) => {
4746
return;
4847
};
4948

50-
constructor() {
51-
super();
52-
}
53-
5449
@postConstruct()
5550
protected init(): void {
5651
this.arduinoPreferences.ready.then(() => {
@@ -75,25 +70,25 @@ export class UploadCertificateDialogWidget extends ReactWidget {
7570
})
7671
);
7772

78-
// this.boardsServiceProvider.onAvailableBoardsChanged((availableBoards) => {
79-
// this.availableBoards = availableBoards;
80-
// this.update();
81-
// });
73+
this.boardsServiceProvider.onBoardListDidChange((boardList) => {
74+
this.boardList = boardList;
75+
this.update();
76+
});
8277
}
8378

84-
// private addCertificate(certificate: string) {
85-
// const certString = sanifyCertString(certificate);
79+
private addCertificate(certificate: string) {
80+
const certString = sanifyCertString(certificate);
8681

87-
// if (certString.length > 0) {
88-
// this.certificates.push(sanifyCertString(certificate));
89-
// }
82+
if (certString.length > 0) {
83+
this.certificates.push(sanifyCertString(certificate));
84+
}
9085

91-
// this.preferenceService.set(
92-
// 'arduino.board.certificates',
93-
// this.certificates.join(','),
94-
// PreferenceScope.User
95-
// );
96-
// }
86+
this.preferenceService.set(
87+
'arduino.board.certificates',
88+
this.certificates.join(','),
89+
PreferenceScope.User
90+
);
91+
}
9792

9893
protected openContextMenu(x: number, y: number, cert: string): void {
9994
this.commandRegistry.executeCommand(
@@ -118,17 +113,16 @@ export class UploadCertificateDialogWidget extends ReactWidget {
118113
}
119114

120115
protected render(): React.ReactNode {
121-
// return (
122-
// <CertificateUploaderComponent
123-
// availableBoards={this.availableBoards}
124-
// certificates={this.certificates}
125-
// updatableFqbns={this.updatableFqbns}
126-
// addCertificate={this.addCertificate.bind(this)}
127-
// uploadCertificates={this.uploadCertificates.bind(this)}
128-
// openContextMenu={this.openContextMenu.bind(this)}
129-
// />
130-
// );
131-
return undefined;
116+
return (
117+
<CertificateUploaderComponent
118+
boardList={this.boardList}
119+
certificates={this.certificates}
120+
updatableFqbns={this.updatableFqbns}
121+
addCertificate={this.addCertificate.bind(this)}
122+
uploadCertificates={this.uploadCertificates.bind(this)}
123+
openContextMenu={this.openContextMenu.bind(this)}
124+
/>
125+
);
132126
}
133127
}
134128

@@ -138,7 +132,7 @@ export class UploadCertificateDialogProps extends DialogProps {}
138132
@injectable()
139133
export class UploadCertificateDialog extends AbstractDialog<void> {
140134
@inject(UploadCertificateDialogWidget)
141-
protected readonly widget: UploadCertificateDialogWidget;
135+
private readonly widget: UploadCertificateDialogWidget;
142136

143137
private busy = false;
144138

arduino-ide-extension/src/browser/dialogs/certificate-uploader/select-board-components.tsx

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import * as React from '@theia/core/shared/react';
33
import {
44
BoardList,
55
BoardListItem,
6+
BoardListItemWithBoard,
67
getInferredBoardOrBoard,
8+
isInferredBoardListItem,
79
} from '../../../common/protocol/board-list';
810
import { boardIdentifierEquals } from '../../../common/protocol/boards-service';
911
import { ArduinoSelect } from '../../widgets/arduino-select';
@@ -19,8 +21,8 @@ export const SelectBoardComponent = ({
1921
}: {
2022
boardList: BoardList;
2123
updatableFqbns: string[];
22-
onItemSelect: (item: Required<BoardListItem> | null) => void;
23-
selectedItem: Required<BoardListItem> | null;
24+
onItemSelect: (item: BoardListItemWithBoard | null) => void;
25+
selectedItem: BoardListItemWithBoard | null;
2426
busy: boolean;
2527
}): React.ReactElement => {
2628
const [selectOptions, setSelectOptions] = React.useState<BoardOption[]>([]);
@@ -32,7 +34,7 @@ export const SelectBoardComponent = ({
3234
onItemSelect(
3335
(boardOpt &&
3436
boardList.boards.find(
35-
(board) => board.board.fqbn === boardOpt.value
37+
(item) => getInferredBoardOrBoard(item)?.fqbn === boardOpt.value
3638
)) ||
3739
null
3840
);
@@ -50,27 +52,31 @@ export const SelectBoardComponent = ({
5052
'arduino/certificate/selectBoard',
5153
'Select a board...'
5254
);
53-
const updatableBoards = boardList.boards.filter(
54-
(item) => item.board.fqbn && updatableFqbns.includes(item.board.fqbn)
55-
);
55+
const updatableBoards = boardList.boards.filter((item) => {
56+
const fqbn = getInferredBoardOrBoard(item)?.fqbn;
57+
return fqbn && updatableFqbns.includes(fqbn);
58+
});
5659
let selBoard = -1;
5760
const selectedItem: BoardListItem | undefined =
5861
boardList[boardList.selectedIndex];
5962
const selectedBoard = selectedItem
6063
? getInferredBoardOrBoard(selectedItem)
6164
: undefined;
6265
const boardsList: BoardOption[] = updatableBoards.map((item, i) => {
63-
if (!!selectedBoard && boardIdentifierEquals(item.board, selectedBoard)) {
66+
const board = isInferredBoardListItem(item)
67+
? item.inferredBoard
68+
: item.board;
69+
if (!!selectedBoard && boardIdentifierEquals(board, selectedBoard)) {
6470
selBoard = i;
6571
}
6672
return {
6773
label: nls.localize(
6874
'arduino/certificate/boardAtPort',
6975
'{0} at {1}',
70-
item.board.name,
76+
board.name,
7177
item.port?.address ?? ''
7278
),
73-
value: item.board.fqbn || '',
79+
value: board.fqbn || '',
7480
};
7581
});
7682

@@ -92,7 +98,6 @@ export const SelectBoardComponent = ({
9298

9399
selectOption(boardsList[selBoard] || null);
94100
}, [busy, boardList, selectOption, updatableFqbns, selectedItem]);
95-
96101
return (
97102
<ArduinoSelect
98103
id="board-select"
@@ -102,11 +107,17 @@ export const SelectBoardComponent = ({
102107
options={selectOptions}
103108
value={
104109
(selectedItem && {
105-
value: selectedItem.board.fqbn,
110+
value: (isInferredBoardListItem(selectedItem)
111+
? selectedItem.inferredBoard
112+
: selectedItem.board
113+
).fqbn,
106114
label: nls.localize(
107115
'arduino/certificate/boardAtPort',
108116
'{0} at {1}',
109-
selectedItem.board.name,
117+
(isInferredBoardListItem(selectedItem)
118+
? selectedItem.inferredBoard
119+
: selectedItem.board
120+
).name,
110121
selectedItem.port.address ?? ''
111122
),
112123
}) ||

arduino-ide-extension/src/browser/style/boards-config-dialog.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ div#select-board-dialog .selectBoardContainer {
1616
height: 100%;
1717
}
1818

19-
#select-board-dialog .head {
19+
.select-board-dialog .head {
2020
margin: 5px;
2121
}
2222

arduino-ide-extension/src/common/protocol/board-list.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ export type InferredBoardListItem =
8383
| BoardSelectedBoardListItem
8484
| BoardOverriddenBoardListItem;
8585

86+
export type BoardListItemWithBoard =
87+
| InferredBoardListItem
88+
| Required<BoardListItem>;
89+
8690
export function isInferredBoardListItem(
8791
arg: unknown
8892
): arg is InferredBoardListItem {
@@ -178,7 +182,7 @@ export type BoardList<T extends BoardListItem = BoardListItem> =
178182
/**
179183
* Contains all boards recognized from the detected port, and an optional unrecognized one that is derived from the detected port and the `initParam#selectedBoard`.
180184
*/
181-
get boards(): readonly Required<BoardListItem>[];
185+
get boards(): readonly BoardListItemWithBoard[];
182186

183187
/**
184188
* If `predicate` is not defined, no ports are filtered.
@@ -312,7 +316,7 @@ export function createBoardList(
312316
return _selectedIndex;
313317
};
314318

315-
let _boards: Required<BoardListItem>[] | undefined;
319+
let _boards: BoardListItemWithBoard[] | undefined;
316320
const boardList: BoardList = Object.assign(items, {
317321
boardsConfig,
318322
get selectedIndex() {
@@ -323,7 +327,9 @@ export function createBoardList(
323327
_boards = [];
324328
for (let i = 0; i < length; i++) {
325329
const item = items[i];
326-
if (item.board) {
330+
if (isInferredBoardListItem(item)) {
331+
_boards.push(item);
332+
} else if (item.board?.fqbn) {
327333
_boards.push(<Required<BoardListItem>>item);
328334
}
329335
}

0 commit comments

Comments
 (0)