From d5eaa91ddaae198d984f92f95ee05b267876b1e6 Mon Sep 17 00:00:00 2001 From: Akos Kitta Date: Thu, 27 Jul 2023 17:23:10 +0200 Subject: [PATCH] fix: board select component to show inferred item if any --- .../browser/boards/boards-config-dialog.tsx | 13 +- .../browser/boards/boards-toolbar-item.tsx | 16 ++- .../certificate-uploader-dialog.tsx | 112 +++++++++--------- .../select-board-components.tsx | 35 ++++-- .../browser/style/boards-config-dialog.css | 2 +- .../src/common/protocol/board-list.ts | 12 +- 6 files changed, 104 insertions(+), 86 deletions(-) diff --git a/arduino-ide-extension/src/browser/boards/boards-config-dialog.tsx b/arduino-ide-extension/src/browser/boards/boards-config-dialog.tsx index 8e9bdaf60..8e5257387 100644 --- a/arduino-ide-extension/src/browser/boards/boards-config-dialog.tsx +++ b/arduino-ide-extension/src/browser/boards/boards-config-dialog.tsx @@ -19,6 +19,7 @@ import { emptyBoardsConfig, PortIdentifier, } from '../../common/protocol/boards-service'; +import { Defined } from '../../common/types'; import { NotificationCenter } from '../notification-center'; import { ReactDialog } from '../theia/dialogs/dialogs'; import { BoardsConfigComponent } from './boards-config-component'; @@ -39,7 +40,9 @@ export class BoardsConfigDialog extends ReactDialog { @inject(FrontendApplicationStateService) private readonly appStateService: FrontendApplicationStateService; - private readonly onFilterTextDidChangeEmitter: Emitter; + private readonly onFilterTextDidChangeEmitter: Emitter< + Defined + >; private readonly onBoardSelected = (board: BoardIdentifier): void => { this._boardsConfig.selectedBoard = board; this.update(); @@ -92,13 +95,13 @@ export class BoardsConfigDialog extends ReactDialog { params?: EditBoardsConfigActionParams ): Promise { if (params) { - if (typeof params?.query === 'string') { - this.onFilterTextDidChangeEmitter.fire(params?.query); + if (params.query || typeof params.query === 'string') { + this.onFilterTextDidChangeEmitter.fire(params.query); } - if (params?.selectedPort) { + if (params.selectedPort) { this._boardsConfig.selectedPort = params.selectedPort; } - if (params?.selectedBoard) { + if (params.selectedBoard) { this._boardsConfig.selectedBoard = params.selectedBoard; } } diff --git a/arduino-ide-extension/src/browser/boards/boards-toolbar-item.tsx b/arduino-ide-extension/src/browser/boards/boards-toolbar-item.tsx index a995fa075..4aa6484a8 100644 --- a/arduino-ide-extension/src/browser/boards/boards-toolbar-item.tsx +++ b/arduino-ide-extension/src/browser/boards/boards-toolbar-item.tsx @@ -35,10 +35,6 @@ export namespace BoardsDropDown { readonly coords: BoardsDropDownListCoords | 'hidden'; readonly boardList: BoardListUI; readonly openBoardsConfig: () => void; - /** - * Hides the board list dropdown, if it's visible. Otherwise, NOOP. - */ - readonly hide: () => void; } } @@ -218,7 +214,6 @@ export class BoardListDropDown extends React.Component { event.preventDefault(); event.stopPropagation(); onRevert({ selectedBoard: inferredItem.board, selectedPort: port }); - this.props.hide(); }} /> ) : undefined; @@ -312,6 +307,16 @@ export class BoardsToolBarItem extends React.Component< 'fa', protocolIcon ); + const originalOnSelect = boardList.onSelect; + boardList['onSelect'] = (params) => { + this.hide(); + return originalOnSelect.bind(boardList)(params); + }; + const originalOnEdit = boardList.onEdit; + boardList['onEdit'] = (params) => { + this.hide(); + return originalOnEdit.bind(boardList)(params); + }; return (
boardList.onEdit({ query: { action: 'clear-if-not-empty' } }) } - hide={this.hide} > ); diff --git a/arduino-ide-extension/src/browser/dialogs/certificate-uploader/certificate-uploader-dialog.tsx b/arduino-ide-extension/src/browser/dialogs/certificate-uploader/certificate-uploader-dialog.tsx index 0ade63912..c014e59c6 100644 --- a/arduino-ide-extension/src/browser/dialogs/certificate-uploader/certificate-uploader-dialog.tsx +++ b/arduino-ide-extension/src/browser/dialogs/certificate-uploader/certificate-uploader-dialog.tsx @@ -1,56 +1,51 @@ -import * as React from '@theia/core/shared/react'; +import { DialogProps } from '@theia/core/lib/browser/dialogs'; +import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state'; +import { + PreferenceScope, + PreferenceService, +} from '@theia/core/lib/browser/preferences/preference-service'; +import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget'; +import { CommandRegistry } from '@theia/core/lib/common/command'; +import { nls } from '@theia/core/lib/common/nls'; +import type { Message } from '@theia/core/shared/@phosphor/messaging'; +import { Widget } from '@theia/core/shared/@phosphor/widgets'; import { inject, injectable, postConstruct, } from '@theia/core/shared/inversify'; -import { DialogProps } from '@theia/core/lib/browser/dialogs'; -import { AbstractDialog } from '../../theia/dialogs/dialogs'; -import { Widget } from '@theia/core/shared/@phosphor/widgets'; -import { Message } from '@theia/core/shared/@phosphor/messaging'; -import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget'; -import { BoardsServiceProvider } from '../../boards/boards-service-provider'; -// import { CertificateUploaderComponent } from './certificate-uploader-component'; -import { ArduinoPreferences } from '../../arduino-preferences'; -import { PreferenceService } from '@theia/core/lib/browser/preferences/preference-service'; -import { CommandRegistry } from '@theia/core/lib/common/command'; -import { certificateList } from './utils'; +import * as React from '@theia/core/shared/react'; import { ArduinoFirmwareUploader } from '../../../common/protocol/arduino-firmware-uploader'; -import { nls } from '@theia/core/lib/common'; -import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state'; +import { createBoardList } from '../../../common/protocol/board-list'; +import { ArduinoPreferences } from '../../arduino-preferences'; +import { BoardsServiceProvider } from '../../boards/boards-service-provider'; +import { AbstractDialog } from '../../theia/dialogs/dialogs'; +import { CertificateUploaderComponent } from './certificate-uploader-component'; +import { certificateList, sanifyCertString } from './utils'; @injectable() export class UploadCertificateDialogWidget extends ReactWidget { @inject(BoardsServiceProvider) - protected readonly boardsServiceProvider: BoardsServiceProvider; - + private readonly boardsServiceProvider: BoardsServiceProvider; @inject(ArduinoPreferences) - protected readonly arduinoPreferences: ArduinoPreferences; - + private readonly arduinoPreferences: ArduinoPreferences; @inject(PreferenceService) - protected readonly preferenceService: PreferenceService; - + private readonly preferenceService: PreferenceService; @inject(CommandRegistry) - protected readonly commandRegistry: CommandRegistry; - + private readonly commandRegistry: CommandRegistry; @inject(ArduinoFirmwareUploader) - protected readonly arduinoFirmwareUploader: ArduinoFirmwareUploader; - + private readonly arduinoFirmwareUploader: ArduinoFirmwareUploader; @inject(FrontendApplicationStateService) private readonly appStateService: FrontendApplicationStateService; - protected certificates: string[] = []; - protected updatableFqbns: string[] = []; - // protected availableBoards: AvailableBoard[] = []; + private certificates: string[] = []; + private updatableFqbns: string[] = []; + private boardList = createBoardList({}); - public busyCallback = (busy: boolean) => { + busyCallback = (busy: boolean) => { return; }; - constructor() { - super(); - } - @postConstruct() protected init(): void { this.arduinoPreferences.ready.then(() => { @@ -75,25 +70,25 @@ export class UploadCertificateDialogWidget extends ReactWidget { }) ); - // this.boardsServiceProvider.onAvailableBoardsChanged((availableBoards) => { - // this.availableBoards = availableBoards; - // this.update(); - // }); + this.boardsServiceProvider.onBoardListDidChange((boardList) => { + this.boardList = boardList; + this.update(); + }); } - // private addCertificate(certificate: string) { - // const certString = sanifyCertString(certificate); + private addCertificate(certificate: string) { + const certString = sanifyCertString(certificate); - // if (certString.length > 0) { - // this.certificates.push(sanifyCertString(certificate)); - // } + if (certString.length > 0) { + this.certificates.push(sanifyCertString(certificate)); + } - // this.preferenceService.set( - // 'arduino.board.certificates', - // this.certificates.join(','), - // PreferenceScope.User - // ); - // } + this.preferenceService.set( + 'arduino.board.certificates', + this.certificates.join(','), + PreferenceScope.User + ); + } protected openContextMenu(x: number, y: number, cert: string): void { this.commandRegistry.executeCommand( @@ -118,17 +113,16 @@ export class UploadCertificateDialogWidget extends ReactWidget { } protected render(): React.ReactNode { - // return ( - // - // ); - return undefined; + return ( + + ); } } @@ -138,7 +132,7 @@ export class UploadCertificateDialogProps extends DialogProps {} @injectable() export class UploadCertificateDialog extends AbstractDialog { @inject(UploadCertificateDialogWidget) - protected readonly widget: UploadCertificateDialogWidget; + private readonly widget: UploadCertificateDialogWidget; private busy = false; diff --git a/arduino-ide-extension/src/browser/dialogs/certificate-uploader/select-board-components.tsx b/arduino-ide-extension/src/browser/dialogs/certificate-uploader/select-board-components.tsx index bb2cf16f6..a594d73c9 100644 --- a/arduino-ide-extension/src/browser/dialogs/certificate-uploader/select-board-components.tsx +++ b/arduino-ide-extension/src/browser/dialogs/certificate-uploader/select-board-components.tsx @@ -3,7 +3,9 @@ import * as React from '@theia/core/shared/react'; import { BoardList, BoardListItem, + BoardListItemWithBoard, getInferredBoardOrBoard, + isInferredBoardListItem, } from '../../../common/protocol/board-list'; import { boardIdentifierEquals } from '../../../common/protocol/boards-service'; import { ArduinoSelect } from '../../widgets/arduino-select'; @@ -19,8 +21,8 @@ export const SelectBoardComponent = ({ }: { boardList: BoardList; updatableFqbns: string[]; - onItemSelect: (item: Required | null) => void; - selectedItem: Required | null; + onItemSelect: (item: BoardListItemWithBoard | null) => void; + selectedItem: BoardListItemWithBoard | null; busy: boolean; }): React.ReactElement => { const [selectOptions, setSelectOptions] = React.useState([]); @@ -32,7 +34,7 @@ export const SelectBoardComponent = ({ onItemSelect( (boardOpt && boardList.boards.find( - (board) => board.board.fqbn === boardOpt.value + (item) => getInferredBoardOrBoard(item)?.fqbn === boardOpt.value )) || null ); @@ -50,9 +52,10 @@ export const SelectBoardComponent = ({ 'arduino/certificate/selectBoard', 'Select a board...' ); - const updatableBoards = boardList.boards.filter( - (item) => item.board.fqbn && updatableFqbns.includes(item.board.fqbn) - ); + const updatableBoards = boardList.boards.filter((item) => { + const fqbn = getInferredBoardOrBoard(item)?.fqbn; + return fqbn && updatableFqbns.includes(fqbn); + }); let selBoard = -1; const selectedItem: BoardListItem | undefined = boardList[boardList.selectedIndex]; @@ -60,17 +63,20 @@ export const SelectBoardComponent = ({ ? getInferredBoardOrBoard(selectedItem) : undefined; const boardsList: BoardOption[] = updatableBoards.map((item, i) => { - if (!!selectedBoard && boardIdentifierEquals(item.board, selectedBoard)) { + const board = isInferredBoardListItem(item) + ? item.inferredBoard + : item.board; + if (!!selectedBoard && boardIdentifierEquals(board, selectedBoard)) { selBoard = i; } return { label: nls.localize( 'arduino/certificate/boardAtPort', '{0} at {1}', - item.board.name, + board.name, item.port?.address ?? '' ), - value: item.board.fqbn || '', + value: board.fqbn || '', }; }); @@ -92,7 +98,6 @@ export const SelectBoardComponent = ({ selectOption(boardsList[selBoard] || null); }, [busy, boardList, selectOption, updatableFqbns, selectedItem]); - return ( ; + export function isInferredBoardListItem( arg: unknown ): arg is InferredBoardListItem { @@ -178,7 +182,7 @@ export type BoardList = /** * Contains all boards recognized from the detected port, and an optional unrecognized one that is derived from the detected port and the `initParam#selectedBoard`. */ - get boards(): readonly Required[]; + get boards(): readonly BoardListItemWithBoard[]; /** * If `predicate` is not defined, no ports are filtered. @@ -312,7 +316,7 @@ export function createBoardList( return _selectedIndex; }; - let _boards: Required[] | undefined; + let _boards: BoardListItemWithBoard[] | undefined; const boardList: BoardList = Object.assign(items, { boardsConfig, get selectedIndex() { @@ -323,7 +327,9 @@ export function createBoardList( _boards = []; for (let i = 0; i < length; i++) { const item = items[i]; - if (item.board) { + if (isInferredBoardListItem(item)) { + _boards.push(item); + } else if (item.board?.fqbn) { _boards.push(>item); } }