@@ -9,12 +9,18 @@ import { nls } from '@theia/core/lib/common/nls';
9
9
import React from '@theia/core/shared/react' ;
10
10
import ReactDOM from '@theia/core/shared/react-dom' ;
11
11
import classNames from 'classnames' ;
12
- import { unknownBoard } from '../../common/protocol' ;
12
+ import {
13
+ boardIdentifierEquals ,
14
+ createPlatformIdentifier ,
15
+ serializePlatformIdentifier ,
16
+ unknownBoard ,
17
+ } from '../../common/protocol' ;
13
18
import {
14
19
BoardListItem ,
15
20
getInferredBoardOrBoard ,
16
21
InferredBoardListItem ,
17
22
isInferredBoardListItem ,
23
+ isMultiBoardsBoardListItem ,
18
24
} from '../../common/protocol/board-list' ;
19
25
import {
20
26
BoardListUI ,
@@ -38,7 +44,10 @@ export namespace BoardsDropDown {
38
44
}
39
45
}
40
46
41
- export class BoardListDropDown extends React . Component < BoardsDropDown . Props > {
47
+ export class BoardListDropDown extends React . Component <
48
+ BoardsDropDown . Props ,
49
+ { expandedItems : BoardListItem [ ] }
50
+ > {
42
51
private dropdownElement : HTMLElement ;
43
52
private listRef : React . RefObject < HTMLDivElement > ;
44
53
@@ -52,6 +61,7 @@ export class BoardListDropDown extends React.Component<BoardsDropDown.Props> {
52
61
document . body . appendChild ( list ) ;
53
62
this . dropdownElement = list ;
54
63
}
64
+ this . state = { expandedItems : [ ] } ;
55
65
}
56
66
57
67
override componentDidUpdate ( prevProps : BoardsDropDown . Props ) : void {
@@ -123,7 +133,6 @@ export class BoardListDropDown extends React.Component<BoardsDropDown.Props> {
123
133
const board = getInferredBoardOrBoard ( item ) ;
124
134
const boardLabel = board ?. name ?? unknownBoard ;
125
135
const boardFqbn = board ?. fqbn ;
126
- const vendor = item . metadata ?. vendor ;
127
136
const onDefaultAction = ( ) => {
128
137
if ( board ) {
129
138
onSelect ( { selectedBoard : board , selectedPort : port } ) ;
@@ -166,18 +175,107 @@ export class BoardListDropDown extends React.Component<BoardsDropDown.Props> {
166
175
< div className = "arduino-boards-dropdown-item--board-label noWrapInfo noselect" >
167
176
{ boardLabel }
168
177
</ div >
169
- { vendor && < div className = "vendor" > { vendor } </ div > }
170
178
</ div >
171
179
< div className = "arduino-boards-dropdown-item--port-label noWrapInfo noselect" >
172
180
{ port . addressLabel }
173
181
</ div >
182
+ { this . renderVendors ( item , onSelect ) }
174
183
</ div >
175
184
{ isInferredBoardListItem ( item ) &&
176
185
this . renderActions ( item , onSelect , onEdit ) }
177
186
</ div >
178
187
) ;
179
188
}
180
189
190
+ private renderVendors (
191
+ item : BoardListItem ,
192
+ onSelect : SelectBoardsConfigAction
193
+ ) : React . ReactNode {
194
+ if ( ! isMultiBoardsBoardListItem ( item ) ) {
195
+ return undefined ;
196
+ }
197
+ const inferredBoard = isInferredBoardListItem ( item )
198
+ ? item . inferredBoard
199
+ : undefined ;
200
+ // If the inferred board is not one of the discovered ones, do not show the vendors.
201
+ // It's the same use-case when there is one discoverd board, but the user overrides it.
202
+ if (
203
+ inferredBoard &&
204
+ item . allBoards . every (
205
+ ( otherBoard ) => ! boardIdentifierEquals ( inferredBoard , otherBoard )
206
+ )
207
+ ) {
208
+ return undefined ;
209
+ }
210
+ const expanded = this . state . expandedItems . includes ( item ) ;
211
+ const boards = ! expanded
212
+ ? [ inferredBoard ? inferredBoard : item . board ]
213
+ : item . allBoards ;
214
+ return (
215
+ < div className = "arduino-boards-dropdown-item--vendors noWrapInfo noselect" >
216
+ < div className = { TabBarToolbar . Styles . TAB_BAR_TOOLBAR } >
217
+ < div
218
+ className = { `${ TabBarToolbar . Styles . TAB_BAR_TOOLBAR_ITEM } enabled` }
219
+ >
220
+ { expanded ? (
221
+ < div
222
+ id = "collapse"
223
+ className = { codicon ( 'chevron-down' , true ) }
224
+ onClick = { ( event ) => {
225
+ event . preventDefault ( ) ;
226
+ event . stopPropagation ( ) ;
227
+ this . setState ( ( prevState ) => ( {
228
+ expandedItems : prevState . expandedItems . filter (
229
+ ( expendedItem ) => item !== expendedItem
230
+ ) ,
231
+ } ) ) ;
232
+ } }
233
+ />
234
+ ) : (
235
+ < div
236
+ id = "expand"
237
+ className = { codicon ( 'chevron-right' , true ) }
238
+ onClick = { ( event ) => {
239
+ event . preventDefault ( ) ;
240
+ event . stopPropagation ( ) ;
241
+ this . setState ( ( prevState ) => ( {
242
+ expandedItems : prevState . expandedItems . concat ( item ) ,
243
+ } ) ) ;
244
+ } }
245
+ />
246
+ ) }
247
+ </ div >
248
+ </ div >
249
+ < div >
250
+ { boards . map ( ( board ) => {
251
+ const platformId = createPlatformIdentifier ( board ) ;
252
+ if ( ! platformId ) {
253
+ return undefined ;
254
+ }
255
+ return (
256
+ < div
257
+ key = { board . fqbn }
258
+ className = "vendor"
259
+ onClick = { ( event ) => {
260
+ event . preventDefault ( ) ;
261
+ event . stopPropagation ( ) ;
262
+ this . setState ( ( prevState ) => ( {
263
+ expandedItems : prevState . expandedItems . filter (
264
+ ( expendedItem ) => item !== expendedItem
265
+ ) ,
266
+ } ) ) ;
267
+ onSelect ( { selectedBoard : board , selectedPort : item . port } ) ;
268
+ } }
269
+ >
270
+ { serializePlatformIdentifier ( platformId ) }
271
+ </ div >
272
+ ) ;
273
+ } ) }
274
+ </ div >
275
+ </ div >
276
+ ) ;
277
+ }
278
+
181
279
private renderActions (
182
280
inferredItem : InferredBoardListItem ,
183
281
onRevert : SelectBoardsConfigAction ,
@@ -210,9 +308,10 @@ export class BoardListDropDown extends React.Component<BoardsDropDown.Props> {
210
308
className = { codicon ( 'discard' , true ) }
211
309
title = { nls . localize (
212
310
'arduino/board/revertBoardsConfig' ,
213
- "Revert the selected '{0}' board to '{1}' detected on '{2}'" ,
214
- inferredItem . inferredBoard . name ,
215
- inferredItem . board . name ,
311
+ "Use '{0}' discovered on '{1}'" ,
312
+ `${ inferredItem . board . name } ${
313
+ inferredItem . board . fqbn ? ` (${ inferredItem . board . fqbn } )` : ''
314
+ } `,
216
315
port . address
217
316
) }
218
317
onClick = { ( event ) => {
0 commit comments