mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-14 06:46:36 +00:00
Added dialog implementation
Signed-off-by: jbicker <jan.bicker@typefox.io>
This commit is contained in:
parent
4c66dec36e
commit
769689ff6d
@ -62,11 +62,11 @@ export class ArduinoToolbarMenuContribution implements MenuContribution {
|
|||||||
|
|
||||||
|
|
||||||
protected getPort(board: Board): string {
|
protected getPort(board: Board): string {
|
||||||
if(AttachedSerialBoard.is(board)){
|
if (AttachedSerialBoard.is(board)) {
|
||||||
return board.port;
|
return board.port;
|
||||||
}
|
}
|
||||||
if(AttachedNetworkBoard.is(board)) {
|
if (AttachedNetworkBoard.is(board)) {
|
||||||
return 'netport' + board.port;
|
return 'netport: ' + board.port;
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ export class ArduinoToolbarMenuContribution implements MenuContribution {
|
|||||||
registerMenus(registry: MenuModelRegistry) {
|
registerMenus(registry: MenuModelRegistry) {
|
||||||
registry.registerMenuAction([...CommonMenus.FILE, '0_new_sletch'], {
|
registry.registerMenuAction([...CommonMenus.FILE, '0_new_sletch'], {
|
||||||
commandId: ArduinoCommands.NEW_SKETCH.id
|
commandId: ArduinoCommands.NEW_SKETCH.id
|
||||||
})
|
});
|
||||||
|
|
||||||
registry.registerMenuAction(ArduinoToolbarContextMenu.OPEN_GROUP, {
|
registry.registerMenuAction(ArduinoToolbarContextMenu.OPEN_GROUP, {
|
||||||
commandId: ArduinoCommands.OPEN_FILE_NAVIGATOR.id,
|
commandId: ArduinoCommands.OPEN_FILE_NAVIGATOR.id,
|
||||||
|
@ -27,7 +27,8 @@ import { ArduinoToolbarContextMenu } from './arduino-file-menu';
|
|||||||
import { Sketch, SketchesService } from '../common/protocol/sketches-service';
|
import { Sketch, SketchesService } from '../common/protocol/sketches-service';
|
||||||
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
||||||
import { CommonCommands } from '@theia/core/lib/browser/common-frontend-contribution'
|
import { CommonCommands } from '@theia/core/lib/browser/common-frontend-contribution'
|
||||||
import { BoardsToolBarItem } from './components/boards-toolbar-item';
|
import { BoardsToolBarItem } from './boards/boards-toolbar-item';
|
||||||
|
import { SelectBoardsDialog } from './boards/select-board-dialog';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class ArduinoFrontendContribution implements TabBarToolbarContribution, CommandContribution {
|
export class ArduinoFrontendContribution implements TabBarToolbarContribution, CommandContribution {
|
||||||
@ -86,6 +87,9 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
|
|||||||
@inject(SketchesService)
|
@inject(SketchesService)
|
||||||
protected readonly sketches: SketchesService;
|
protected readonly sketches: SketchesService;
|
||||||
|
|
||||||
|
@inject(SelectBoardsDialog)
|
||||||
|
protected readonly selectBoardsDialog: SelectBoardsDialog;
|
||||||
|
|
||||||
@postConstruct()
|
@postConstruct()
|
||||||
protected async init(): Promise<void> {
|
protected async init(): Promise<void> {
|
||||||
// This is a hack. Otherwise, the backend services won't bind.
|
// This is a hack. Otherwise, the backend services won't bind.
|
||||||
@ -227,13 +231,26 @@ export class ArduinoFrontendContribution implements TabBarToolbarContribution, C
|
|||||||
registry.registerCommand(ArduinoCommands.SELECT_BOARD, {
|
registry.registerCommand(ArduinoCommands.SELECT_BOARD, {
|
||||||
isEnabled: () => true,
|
isEnabled: () => true,
|
||||||
execute: (board: Board) => {
|
execute: (board: Board) => {
|
||||||
console.log("SELECT BOARD HERE", board);
|
this.boardService.selectBoard(board).then(() => {
|
||||||
|
return this.boardService.getSelectBoard();
|
||||||
|
}).then(board => {
|
||||||
|
console.log("and the selected board is", board);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
registry.registerCommand(ArduinoCommands.OPEN_BOARDS_DIALOG, {
|
registry.registerCommand(ArduinoCommands.OPEN_BOARDS_DIALOG, {
|
||||||
isEnabled: () => true,
|
isEnabled: () => true,
|
||||||
execute: () => {
|
execute: async () => {
|
||||||
console.log("OPEN THE DIALOG HERE");
|
const boardAndPort = await this.selectBoardsDialog.open();
|
||||||
|
if(boardAndPort && boardAndPort.board){
|
||||||
|
const selectedBoard = {
|
||||||
|
fqbn: boardAndPort.board.fqbn,
|
||||||
|
name: boardAndPort.board.name,
|
||||||
|
port: boardAndPort.port
|
||||||
|
}
|
||||||
|
this.boardService.selectBoard(selectedBoard);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,8 @@ import { CustomApplicationShell } from './customization/custom-application-shell
|
|||||||
import { CustomFrontendApplication } from './customization/custom-frontend-application';
|
import { CustomFrontendApplication } from './customization/custom-frontend-application';
|
||||||
import { EditorWidgetFactory } from '@theia/editor/lib/browser/editor-widget-factory';
|
import { EditorWidgetFactory } from '@theia/editor/lib/browser/editor-widget-factory';
|
||||||
import { CustomEditorWidgetFactory } from './customization/custom-editor-widget-factory';
|
import { CustomEditorWidgetFactory } from './customization/custom-editor-widget-factory';
|
||||||
|
import { SelectBoardsDialog, SelectBoardsDialogProps } from './boards/select-board-dialog';
|
||||||
|
import { SelectBoardDialogWidget } from './boards/select-board-dialog-widget';
|
||||||
|
|
||||||
export default new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Unbind, isBound: interfaces.IsBound, rebind: interfaces.Rebind) => {
|
export default new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Unbind, isBound: interfaces.IsBound, rebind: interfaces.Rebind) => {
|
||||||
// Commands and toolbar items
|
// Commands and toolbar items
|
||||||
@ -94,6 +96,13 @@ export default new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Un
|
|||||||
}));
|
}));
|
||||||
bind(FrontendApplicationContribution).toService(BoardsListWidgetFrontendContribution);
|
bind(FrontendApplicationContribution).toService(BoardsListWidgetFrontendContribution);
|
||||||
|
|
||||||
|
// Board select dialog
|
||||||
|
bind(SelectBoardDialogWidget).toSelf().inSingletonScope();
|
||||||
|
bind(SelectBoardsDialog).toSelf().inSingletonScope();
|
||||||
|
bind(SelectBoardsDialogProps).toConstantValue({
|
||||||
|
title: 'Select Board'
|
||||||
|
})
|
||||||
|
|
||||||
// Core service
|
// Core service
|
||||||
bind(CoreService)
|
bind(CoreService)
|
||||||
.toDynamicValue(context => WebSocketConnectionProvider.createProxy(context.container, CoreServicePath))
|
.toDynamicValue(context => WebSocketConnectionProvider.createProxy(context.container, CoreServicePath))
|
||||||
|
@ -0,0 +1,230 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { ReactWidget } from '@theia/core/lib/browser';
|
||||||
|
import { injectable, inject } from 'inversify';
|
||||||
|
import { BoardsService, Board, BoardPackage, AttachedSerialBoard } from '../../common/protocol/boards-service';
|
||||||
|
import { BoardsNotificationService } from '../boards-notification-service';
|
||||||
|
import { Emitter, Event } from '@theia/core';
|
||||||
|
|
||||||
|
export interface BoardAndPortSelection {
|
||||||
|
board?: Board;
|
||||||
|
port?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace SelectableBoardsItem {
|
||||||
|
export interface Props {
|
||||||
|
board: Board,
|
||||||
|
selected: boolean,
|
||||||
|
onClick: (selection: BoardAndPortSelection) => void
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SelectableBoardsItem extends React.Component<SelectableBoardsItem.Props> {
|
||||||
|
|
||||||
|
render(): React.ReactNode {
|
||||||
|
return <div onClick={this.select} className={`item ${this.props.selected ? 'selected': ''}`}>{this.props.board.name}</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
protected readonly select = (() => {
|
||||||
|
this.props.onClick({ board: this.props.board })
|
||||||
|
}).bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace SelectablePortsItem {
|
||||||
|
export interface Props {
|
||||||
|
port: string,
|
||||||
|
selected: boolean,
|
||||||
|
onClick: (selection: BoardAndPortSelection) => void
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SelectablePortsItem extends React.Component<SelectablePortsItem.Props> {
|
||||||
|
|
||||||
|
render(): React.ReactNode {
|
||||||
|
return <div onClick={() => this.props.onClick({ port: this.props.port })} className={`item ${this.props.selected ? 'selected': ''}`}>{this.props.port}</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
protected readonly select = (() => {
|
||||||
|
this.props.onClick({ port: this.props.port })
|
||||||
|
}).bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace BoardAndPortSelectionComponent {
|
||||||
|
export interface Props {
|
||||||
|
boardsService: BoardsService;
|
||||||
|
onSelect: (selection: BoardAndPortSelection) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface State {
|
||||||
|
boards: Board[];
|
||||||
|
ports: string[];
|
||||||
|
selection: BoardAndPortSelection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BoardAndPortSelectionComponent extends React.Component<BoardAndPortSelectionComponent.Props, BoardAndPortSelectionComponent.State> {
|
||||||
|
|
||||||
|
protected allBoards: Board[] = [];
|
||||||
|
|
||||||
|
constructor(props: BoardAndPortSelectionComponent.Props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
boards: [],
|
||||||
|
ports: [],
|
||||||
|
selection: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.searchAvailableBoards();
|
||||||
|
this.setPorts();
|
||||||
|
}
|
||||||
|
|
||||||
|
render(): React.ReactNode {
|
||||||
|
return <React.Fragment>
|
||||||
|
<div className='body'>
|
||||||
|
<div className='left'>
|
||||||
|
<div className='title'>
|
||||||
|
BOARDS
|
||||||
|
</div>
|
||||||
|
<div className='search'>
|
||||||
|
<input type='search' placeholder='SEARCH BOARD' onChange={this.doFilter} />
|
||||||
|
</div>
|
||||||
|
<div className='boards list'>
|
||||||
|
{this.state.boards.map(board => <SelectableBoardsItem key={board.name} onClick={this.doSelect} board={board} selected={this.isSelectedBoard(board)}/>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='right'>
|
||||||
|
<div className='title'>
|
||||||
|
PORTS
|
||||||
|
</div>
|
||||||
|
<div className='ports list'>
|
||||||
|
{this.state.ports.map(port => <SelectablePortsItem key={port} onClick={this.doSelect} port={port} selected={this.isSelectedPort(port)}/>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</React.Fragment>
|
||||||
|
}
|
||||||
|
|
||||||
|
protected readonly isSelectedBoard = ((board: Board) => {
|
||||||
|
return (this.state.selection.board && this.state.selection.board === board) || false;
|
||||||
|
});
|
||||||
|
|
||||||
|
protected readonly isSelectedPort = ((port: string) => {
|
||||||
|
return (this.state.selection.port && this.state.selection.port === port) || false;
|
||||||
|
});
|
||||||
|
|
||||||
|
protected readonly doSelect = (boardAndPortSelection: BoardAndPortSelection) => {
|
||||||
|
const selection = this.state.selection;
|
||||||
|
if (boardAndPortSelection.board) {
|
||||||
|
selection.board = boardAndPortSelection.board;
|
||||||
|
}
|
||||||
|
if (boardAndPortSelection.port) {
|
||||||
|
selection.port = boardAndPortSelection.port;
|
||||||
|
}
|
||||||
|
this.setState({ selection });
|
||||||
|
this.props.onSelect(this.state.selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected sort(items: Board[]): Board[] {
|
||||||
|
return items.sort((a, b) => {
|
||||||
|
if (a.name < b.name) {
|
||||||
|
return -1;
|
||||||
|
} else if (a.name === b.name) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected readonly doFilter = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const boards = this.allBoards.filter(board => board.name.toLowerCase().indexOf(event.target.value.toLowerCase()) >= 0);
|
||||||
|
this.setState({ boards })
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async searchAvailableBoards() {
|
||||||
|
const boardPkg = await this.props.boardsService.search({});
|
||||||
|
const boards = [].concat.apply([], boardPkg.items.map<Board[]>(item => item.boards)) as Board[];
|
||||||
|
this.allBoards = this.sort(boards);
|
||||||
|
this.setState({ boards: this.allBoards });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async setPorts() {
|
||||||
|
const ports: string[] = [];
|
||||||
|
const attached = await this.props.boardsService.getAttachedBoards();
|
||||||
|
attached.boards.forEach(board => {
|
||||||
|
if (AttachedSerialBoard.is(board)) {
|
||||||
|
ports.push(board.port);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.setState({ ports });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@injectable()
|
||||||
|
export class SelectBoardDialogWidget extends ReactWidget {
|
||||||
|
|
||||||
|
@inject(BoardsService)
|
||||||
|
protected readonly boardsService: BoardsService;
|
||||||
|
@inject(BoardsNotificationService)
|
||||||
|
protected readonly boardsNotificationService: BoardsNotificationService;
|
||||||
|
|
||||||
|
protected readonly onChangedEmitter = new Emitter<BoardAndPortSelection>();
|
||||||
|
|
||||||
|
boardAndPort: BoardAndPortSelection = {};
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.id = 'select-board-dialog';
|
||||||
|
|
||||||
|
this.toDispose.push(this.onChangedEmitter);
|
||||||
|
}
|
||||||
|
|
||||||
|
get onChanged(): Event<BoardAndPortSelection> {
|
||||||
|
return this.onChangedEmitter.event;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fireChanged(boardAndPort: BoardAndPortSelection): void {
|
||||||
|
this.onChangedEmitter.fire(boardAndPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render(): React.ReactNode {
|
||||||
|
let content: React.ReactNode;
|
||||||
|
|
||||||
|
const boardsServiceDelegate = this.boardsService;
|
||||||
|
const boardsService: BoardsService = {
|
||||||
|
getAttachedBoards: () => boardsServiceDelegate.getAttachedBoards(),
|
||||||
|
selectBoard: (board: Board) => boardsServiceDelegate.selectBoard(board),
|
||||||
|
getSelectBoard: () => boardsServiceDelegate.getSelectBoard(),
|
||||||
|
search: (options: { query?: string }) => boardsServiceDelegate.search(options),
|
||||||
|
install: async (item: BoardPackage) => {
|
||||||
|
await boardsServiceDelegate.install(item);
|
||||||
|
this.boardsNotificationService.notifyBoardsInstalled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
content = <React.Fragment>
|
||||||
|
<div className='selectBoardContainer'>
|
||||||
|
<div className='head'>
|
||||||
|
<div className='title'>
|
||||||
|
Select Other Board & Port
|
||||||
|
</div>
|
||||||
|
<div className='text'>
|
||||||
|
Select both a BOARD and a PORT if you want to upload a sketch.<br />
|
||||||
|
If you only select a BOARD you will be able just to compile, but not to upload your sketch.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<BoardAndPortSelectionComponent boardsService={boardsService} onSelect={this.onSelect} />
|
||||||
|
</div>
|
||||||
|
</React.Fragment>
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected readonly onSelect = (selection: BoardAndPortSelection) => { this.doOnSelect(selection) };
|
||||||
|
protected doOnSelect(selection: BoardAndPortSelection) {
|
||||||
|
this.boardAndPort = selection;
|
||||||
|
this.fireChanged(this.boardAndPort);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
import { AbstractDialog, DialogProps, Widget, Panel, DialogError } from '@theia/core/lib/browser';
|
||||||
|
import { injectable, inject } from 'inversify';
|
||||||
|
import { SelectBoardDialogWidget, BoardAndPortSelection } from './select-board-dialog-widget';
|
||||||
|
import { Message } from '@phosphor/messaging';
|
||||||
|
import { Disposable } from '@theia/core';
|
||||||
|
|
||||||
|
@injectable()
|
||||||
|
export class SelectBoardsDialogProps extends DialogProps {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@injectable()
|
||||||
|
export class SelectBoardsDialog extends AbstractDialog<BoardAndPortSelection> {
|
||||||
|
|
||||||
|
protected readonly dialogPanel: Panel;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@inject(SelectBoardsDialogProps) protected readonly props: SelectBoardsDialogProps,
|
||||||
|
@inject(SelectBoardDialogWidget) protected readonly widget: SelectBoardDialogWidget
|
||||||
|
) {
|
||||||
|
super({ title: props.title });
|
||||||
|
|
||||||
|
this.dialogPanel = new Panel();
|
||||||
|
this.dialogPanel.addWidget(this.widget);
|
||||||
|
|
||||||
|
this.toDispose.push(this.widget.onChanged(() => this.update()));
|
||||||
|
|
||||||
|
this.toDispose.push(this.dialogPanel);
|
||||||
|
|
||||||
|
this.appendCloseButton('CANCEL');
|
||||||
|
this.appendAcceptButton('OK');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onAfterAttach(msg: Message): void {
|
||||||
|
Widget.attach(this.dialogPanel, this.contentNode);
|
||||||
|
|
||||||
|
this.toDisposeOnDetach.push(Disposable.create(() => {
|
||||||
|
Widget.detach(this.dialogPanel);
|
||||||
|
}))
|
||||||
|
|
||||||
|
super.onAfterAttach(msg);
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onUpdateRequest(msg: Message) {
|
||||||
|
super.onUpdateRequest(msg);
|
||||||
|
|
||||||
|
this.widget.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onActivateRequest(msg: Message): void {
|
||||||
|
this.widget.activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected handleEnter(event: KeyboardEvent): boolean | void {
|
||||||
|
if (event.target instanceof HTMLTextAreaElement) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected isValid(value: BoardAndPortSelection): DialogError {
|
||||||
|
if(!value.board) {
|
||||||
|
if(value.port) {
|
||||||
|
return 'Please pick the Board connected to the Port you have selected';
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
get value(): BoardAndPortSelection {
|
||||||
|
return this.widget.boardAndPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async accept(): Promise<void> {
|
||||||
|
super.accept();
|
||||||
|
}
|
||||||
|
}
|
@ -97,3 +97,15 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
color: var(--theia-ui-font-color3);
|
color: var(--theia-ui-font-color3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div#select-board-dialog .selectBoardContainer .body {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#select-board-dialog .selectBoardContainer .head {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#select-board-dialog .selectBoardContainer .body .list .item.selected {
|
||||||
|
background: #aaaaaa;
|
||||||
|
}
|
@ -4,8 +4,8 @@ export const BoardsServicePath = '/services/boards-service';
|
|||||||
export const BoardsService = Symbol('BoardsService');
|
export const BoardsService = Symbol('BoardsService');
|
||||||
export interface BoardsService {
|
export interface BoardsService {
|
||||||
getAttachedBoards(): Promise<{ boards: Board[] }>;
|
getAttachedBoards(): Promise<{ boards: Board[] }>;
|
||||||
selectBoard(board: Board): Promise<void>;
|
selectBoard(board: Board | AttachedSerialBoard | AttachedNetworkBoard): Promise<void>;
|
||||||
getSelectBoard(): Promise<Board | undefined>;
|
getSelectBoard(): Promise<Board | AttachedSerialBoard | AttachedNetworkBoard | undefined>;
|
||||||
|
|
||||||
search(options: { query?: string }): Promise<{ items: BoardPackage[] }>;
|
search(options: { query?: string }): Promise<{ items: BoardPackage[] }>;
|
||||||
install(item: BoardPackage): Promise<void>;
|
install(item: BoardPackage): Promise<void>;
|
||||||
@ -23,31 +23,29 @@ export interface Board {
|
|||||||
|
|
||||||
export interface AttachedSerialBoard extends Board {
|
export interface AttachedSerialBoard extends Board {
|
||||||
port: string;
|
port: string;
|
||||||
serialNumber: string;
|
type: 'serial';
|
||||||
productID: string;
|
serialNumber?: string;
|
||||||
vendorID: string;
|
productID?: string;
|
||||||
|
vendorID?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace AttachedSerialBoard {
|
export namespace AttachedSerialBoard {
|
||||||
export function is(b: Board): b is AttachedSerialBoard {
|
export function is(b: Board): b is AttachedSerialBoard {
|
||||||
return 'port' in b
|
return 'type' in b && (b as Board & { type: any }).type === 'serial' &&
|
||||||
&& 'serialNumber' in b
|
'port' in b && !!(b as Board & { port: any }).port && typeof (b as Board & { port: any }).port === 'string';
|
||||||
&& 'productID' in b
|
|
||||||
&& 'vendorID' in b;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttachedNetworkBoard extends Board {
|
export interface AttachedNetworkBoard extends Board {
|
||||||
info: string;
|
info?: string;
|
||||||
address: string;
|
address?: string;
|
||||||
port: number;
|
port: number;
|
||||||
|
type: 'network';
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace AttachedNetworkBoard {
|
export namespace AttachedNetworkBoard {
|
||||||
export function is(b: Board): b is AttachedNetworkBoard {
|
export function is(b: Board): b is AttachedNetworkBoard {
|
||||||
return 'name' in b
|
return 'type' in b && (b as Board & { type: any }).type === 'network' &&
|
||||||
&& 'info' in b
|
'port' in b && !!(b as Board & { port: any }).port && typeof (b as Board & { port: any }).port === 'number';
|
||||||
&& 'address' in b
|
|
||||||
&& 'port' in b;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ export class BoardsServiceImpl implements BoardsService {
|
|||||||
name: b.getName() || "unknown",
|
name: b.getName() || "unknown",
|
||||||
fqbn: b.getFqbn(),
|
fqbn: b.getFqbn(),
|
||||||
port: b.getPort(),
|
port: b.getPort(),
|
||||||
|
type: 'serial',
|
||||||
serialNumber: b.getSerialnumber(),
|
serialNumber: b.getSerialnumber(),
|
||||||
productID: b.getProductid(),
|
productID: b.getProductid(),
|
||||||
vendorID: b.getVendorid()
|
vendorID: b.getVendorid()
|
||||||
@ -41,6 +42,7 @@ export class BoardsServiceImpl implements BoardsService {
|
|||||||
address: b.getAddress(),
|
address: b.getAddress(),
|
||||||
info: b.getInfo(),
|
info: b.getInfo(),
|
||||||
port: b.getPort(),
|
port: b.getPort(),
|
||||||
|
type: 'network'
|
||||||
});
|
});
|
||||||
|
|
||||||
return { boards: serialBoards.concat(networkBoards) };
|
return { boards: serialBoards.concat(networkBoards) };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user