Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8ca1b94

Browse files
author
Akos Kitta
committedMar 1, 2023
init
Signed-off-by: Akos Kitta <[email protected]>
1 parent f3d3d40 commit 8ca1b94

File tree

15 files changed

+309
-295
lines changed

15 files changed

+309
-295
lines changed
 

‎arduino-ide-extension/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
"@types/p-queue": "^2.3.1",
5959
"@types/ps-tree": "^1.1.0",
6060
"@types/react-tabs": "^2.3.2",
61-
"@types/react-virtualized": "^9.21.21",
6261
"@types/temp": "^0.8.34",
6362
"@types/which": "^1.3.1",
6463
"@vscode/debugprotocol": "^1.51.0",
@@ -95,7 +94,6 @@
9594
"react-perfect-scrollbar": "^1.5.8",
9695
"react-select": "^5.6.0",
9796
"react-tabs": "^3.1.2",
98-
"react-virtualized": "^9.22.3",
9997
"react-window": "^1.8.6",
10098
"semver": "^7.3.2",
10199
"string-natural-compare": "^2.0.3",

‎arduino-ide-extension/src/browser/boards/boards-auto-installer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ export class BoardsAutoInstaller implements FrontendApplicationContribution {
174174
// CLI returns the packages already sorted with the deprecated ones at the end of the list
175175
// in order to ensure the new ones are preferred
176176
const candidates = packagesForBoard.filter(
177-
({ installable, installedVersion }) => installable && !installedVersion
177+
({ installedVersion }) => !installedVersion
178178
);
179179

180180
return candidates[0];

‎arduino-ide-extension/src/browser/style/index.css

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,6 @@ button.theia-button.message-box-dialog-button {
154154
font-size: 14px;
155155
}
156156

157-
.uppercase {
158-
text-transform: uppercase;
159-
}
160-
161157
/* High Contrast Theme rules */
162158
/* TODO: Remove it when the Theia version is upgraded to 1.27.0 and use Theia APIs to implement it*/
163159
.hc-black.hc-theia.theia-hc button.theia-button:hover,

‎arduino-ide-extension/src/browser/style/list-widget.css

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,7 @@
118118
background-color: var(--theia-button-foreground);
119119
color: var(--theia-button-background);
120120
content: attr(uninstall);
121-
}
122-
123-
.component-list-item[min-width~="170px"] .footer {
124-
padding: 5px 5px 0px 0px;
125-
min-height: 35px;
126-
display: flex;
127-
flex-direction: row-reverse;
121+
text-transform: uppercase;
128122
}
129123

130124
.component-list-item .footer {
@@ -155,7 +149,7 @@
155149
/* TODO: Remove it when the Theia version is upgraded to 1.27.0 and use Theia APIs to implement it*/
156150
.hc-black.hc-theia.theia-hc .component-list-item .header .installed:hover:before {
157151
background-color: transparent;
158-
outline: 1px dashed var(--theia-focusBorder);
152+
outline: 1px dashed var(--theia-focusBorder);
159153
}
160154

161155
.hc-black.hc-theia.theia-hc .component-list-item .header .installed:before {

‎arduino-ide-extension/src/browser/widgets/component-list/component-list-item.tsx

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,9 @@ export class ComponentListItem<
88
> extends React.Component<ComponentListItem.Props<T>, ComponentListItem.State> {
99
constructor(props: ComponentListItem.Props<T>) {
1010
super(props);
11-
if (props.item.installable) {
12-
const version = props.item.availableVersions.filter(
13-
(version) => version !== props.item.installedVersion
14-
)[0];
15-
this.state = {
16-
selectedVersion: version,
17-
};
18-
}
11+
this.state = {
12+
selectedVersion: Installable.latest(props.item.availableVersions),
13+
};
1914
}
2015

2116
override render(): React.ReactNode {
@@ -33,24 +28,21 @@ export class ComponentListItem<
3328
}
3429

3530
private async install(item: T): Promise<void> {
36-
const toInstall = this.state.selectedVersion;
37-
const version = this.props.item.availableVersions.filter(
38-
(version) => version !== this.state.selectedVersion
39-
)[0];
40-
this.setState({
41-
selectedVersion: version,
42-
});
31+
this.setState({ state: 'uninstalling' });
4332
try {
44-
await this.props.install(item, toInstall);
45-
} catch {
46-
this.setState({
47-
selectedVersion: toInstall,
48-
});
33+
await this.props.install(item, this.state.selectedVersion);
34+
} finally {
35+
this.setState({ state: undefined });
4936
}
5037
}
5138

5239
private async uninstall(item: T): Promise<void> {
53-
await this.props.uninstall(item);
40+
this.setState({ state: 'uninstalling' });
41+
try {
42+
await this.props.uninstall(item);
43+
} finally {
44+
this.setState({ state: undefined });
45+
}
5446
}
5547

5648
private onVersionChange(version: Installable.Version): void {
@@ -68,5 +60,6 @@ export namespace ComponentListItem {
6860

6961
export interface State {
7062
selectedVersion?: Installable.Version;
63+
state?: 'installing' | 'uninstalling' | undefined;
7164
}
7265
}

‎arduino-ide-extension/src/browser/widgets/component-list/component-list.tsx

Lines changed: 13 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,144 +1,29 @@
1-
import 'react-virtualized/styles.css';
21
import * as React from '@theia/core/shared/react';
3-
import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer';
4-
import {
5-
CellMeasurer,
6-
CellMeasurerCache,
7-
} from 'react-virtualized/dist/commonjs/CellMeasurer';
8-
import type {
9-
ListRowProps,
10-
ListRowRenderer,
11-
} from 'react-virtualized/dist/commonjs/List';
12-
import List from 'react-virtualized/dist/commonjs/List';
2+
import { ItemContent, Virtuoso } from '@theia/core/shared/react-virtuoso';
133
import { ArduinoComponent } from '../../../common/protocol/arduino-component';
144
import { Installable } from '../../../common/protocol/installable';
155
import { ComponentListItem } from './component-list-item';
166
import { ListItemRenderer } from './list-item-renderer';
177

18-
function sameAs<T>(
19-
left: T[],
20-
right: T[],
21-
...compareProps: (keyof T)[]
22-
): boolean {
23-
if (left === right) {
24-
return true;
25-
}
26-
const leftLength = left.length;
27-
if (leftLength !== right.length) {
28-
return false;
29-
}
30-
for (let i = 0; i < leftLength; i++) {
31-
for (const prop of compareProps) {
32-
const leftValue = left[i][prop];
33-
const rightValue = right[i][prop];
34-
if (leftValue !== rightValue) {
35-
return false;
36-
}
37-
}
38-
}
39-
return true;
40-
}
41-
428
export class ComponentList<T extends ArduinoComponent> extends React.Component<
439
ComponentList.Props<T>
4410
> {
45-
private readonly cache: CellMeasurerCache;
46-
private resizeAllFlag: boolean;
47-
private list: List | undefined;
48-
private mostRecentWidth: number | undefined;
49-
50-
constructor(props: ComponentList.Props<T>) {
51-
super(props);
52-
this.cache = new CellMeasurerCache({
53-
defaultHeight: 140,
54-
fixedWidth: true,
55-
});
56-
}
57-
5811
override render(): React.ReactNode {
59-
return (
60-
<AutoSizer>
61-
{({ width, height }) => {
62-
if (this.mostRecentWidth && this.mostRecentWidth !== width) {
63-
this.resizeAllFlag = true;
64-
setTimeout(() => this.clearAll(), 0);
65-
}
66-
this.mostRecentWidth = width;
67-
return (
68-
<List
69-
className={'items-container'}
70-
rowRenderer={this.createItem}
71-
height={height}
72-
width={width}
73-
rowCount={this.props.items.length}
74-
rowHeight={this.cache.rowHeight}
75-
deferredMeasurementCache={this.cache}
76-
ref={this.setListRef}
77-
estimatedRowSize={140}
78-
// If default value, then `react-virtualized` will optimize and list item will not receive a `:hover` event.
79-
// Hence, install and version `<select>` won't be visible even if the mouse cursor is over the `<div>`.
80-
// See https://github.com/bvaughn/react-virtualized/blob/005be24a608add0344284053dae7633be86053b2/source/Grid/Grid.js#L38-L42
81-
scrollingResetTimeInterval={0}
82-
/>
83-
);
84-
}}
85-
</AutoSizer>
86-
);
87-
}
88-
89-
override componentDidUpdate(prevProps: ComponentList.Props<T>): void {
90-
if (
91-
this.resizeAllFlag ||
92-
!sameAs(this.props.items, prevProps.items, 'name', 'installedVersion')
93-
) {
94-
this.clearAll(true);
95-
}
96-
}
97-
98-
private readonly setListRef = (ref: List | null): void => {
99-
this.list = ref || undefined;
100-
};
101-
102-
private clearAll(scrollToTop = false): void {
103-
this.resizeAllFlag = false;
104-
this.cache.clearAll();
105-
if (this.list) {
106-
this.list.recomputeRowHeights();
107-
if (scrollToTop) {
108-
this.list.scrollToPosition(0);
109-
}
110-
}
12+
return <Virtuoso data={this.props.items} itemContent={this.itemContent} />;
11113
}
11214

113-
private readonly createItem: ListRowRenderer = ({
114-
index,
115-
parent,
116-
key,
117-
style,
118-
}: ListRowProps): React.ReactNode => {
119-
const item = this.props.items[index];
15+
private readonly itemContent: ItemContent<T, unknown> = (
16+
index: number,
17+
item: T
18+
) => {
12019
return (
121-
<CellMeasurer
122-
cache={this.cache}
123-
columnIndex={0}
124-
key={key}
125-
rowIndex={index}
126-
parent={parent}
127-
>
128-
{({ registerChild }) => (
129-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
130-
// @ts-ignore
131-
<div ref={registerChild} style={style}>
132-
<ComponentListItem<T>
133-
key={this.props.itemLabel(item)}
134-
item={item}
135-
itemRenderer={this.props.itemRenderer}
136-
install={this.props.install}
137-
uninstall={this.props.uninstall}
138-
/>
139-
</div>
140-
)}
141-
</CellMeasurer>
20+
<ComponentListItem<T>
21+
key={this.props.itemLabel(item)}
22+
item={item}
23+
itemRenderer={this.props.itemRenderer}
24+
install={this.props.install}
25+
uninstall={this.props.uninstall}
26+
/>
14227
);
14328
};
14429
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Installable } from '../../../common/protocol';
2+
3+
export const ItemActionLiterals = [
4+
'installLatest',
5+
'installSelected',
6+
'update',
7+
'remove',
8+
'unknown',
9+
] as const;
10+
export type ItemActionType = typeof ItemActionLiterals[number];
11+
12+
export function itemAction(params: {
13+
installed?: Installable.Version | undefined;
14+
available: Installable.Version[];
15+
selected?: Installable.Version;
16+
}): ItemActionType {
17+
const { installed, available } = params;
18+
const latest = Installable.latest(available);
19+
if (!latest || (installed && !available.includes(installed))) {
20+
return 'unknown';
21+
}
22+
const selected = params.selected ?? latest;
23+
if (installed === selected) {
24+
return 'remove';
25+
}
26+
if (installed) {
27+
return selected === latest && installed !== latest
28+
? 'update'
29+
: 'installSelected';
30+
} else {
31+
return selected === latest ? 'installLatest' : 'installSelected';
32+
}
33+
}

‎arduino-ide-extension/src/browser/widgets/component-list/list-item-renderer.tsx

Lines changed: 106 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ import { ArduinoComponent } from '../../../common/protocol/arduino-component';
66
import { ComponentListItem } from './component-list-item';
77
import { nls } from '@theia/core/lib/common';
88
import { Unknown } from '../../../common/nls';
9+
import { itemAction } from './item-action';
910

1011
@injectable()
1112
export class ListItemRenderer<T extends ArduinoComponent> {
1213
@inject(WindowService)
13-
protected windowService: WindowService;
14+
private readonly windowService: WindowService;
1415

15-
protected onMoreInfoClick = (
16+
private readonly onMoreInfoClick = (
1617
event: React.SyntheticEvent<HTMLAnchorElement, Event>
1718
): void => {
1819
const { target } = event.nativeEvent;
@@ -28,61 +29,31 @@ export class ListItemRenderer<T extends ArduinoComponent> {
2829
uninstall: (item: T) => Promise<void>,
2930
onVersionChange: (version: Installable.Version) => void
3031
): React.ReactNode {
31-
const { item } = input;
32+
const { item, selectedVersion } = input;
33+
const { name, author, installedVersion, availableVersions } = item;
3234
let nameAndAuthor: JSX.Element;
33-
if (item.name && item.author) {
34-
const name = <span className="name">{item.name}</span>;
35-
const author = <span className="author">{item.author}</span>;
35+
if (name && author) {
3636
nameAndAuthor = (
3737
<span>
38-
{name} {nls.localize('arduino/component/by', 'by')} {author}
38+
{<span className="name">{item.name}</span>}{' '}
39+
{nls.localize('arduino/component/by', 'by')}{' '}
40+
{<span className="author">{item.author}</span>}
3941
</span>
4042
);
41-
} else if (item.name) {
43+
} else if (name) {
4244
nameAndAuthor = <span className="name">{item.name}</span>;
45+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
4346
} else if ((item as any).id) {
47+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
4448
nameAndAuthor = <span className="name">{(item as any).id}</span>;
4549
} else {
4650
nameAndAuthor = <span className="name">{Unknown}</span>;
4751
}
48-
const onClickUninstall = () => uninstall(item);
49-
const installedVersion = !!item.installedVersion && (
50-
<div className="version-info">
51-
<span className="version">
52-
{nls.localize(
53-
'arduino/component/version',
54-
'Version {0}',
55-
item.installedVersion
56-
)}
57-
</span>
58-
<span
59-
className="installed uppercase"
60-
onClick={onClickUninstall}
61-
{...{
62-
install: nls.localize('arduino/component/installed', 'Installed'),
63-
uninstall: nls.localize('arduino/component/uninstall', 'Uninstall'),
64-
}}
65-
/>
66-
</div>
67-
);
68-
69-
const summary = <div className="summary">{item.summary}</div>;
70-
const description = <div className="summary">{item.description}</div>;
71-
7252
const moreInfo = !!item.moreInfoLink && (
7353
<a href={item.moreInfoLink} onClick={this.onMoreInfoClick}>
7454
{nls.localize('arduino/component/moreInfo', 'More info')}
7555
</a>
7656
);
77-
const onClickInstall = () => install(item);
78-
const installButton = item.installable && (
79-
<button
80-
className="theia-button secondary install uppercase"
81-
onClick={onClickInstall}
82-
>
83-
{nls.localize('arduino/component/install', 'Install')}
84-
</button>
85-
);
8657

8758
const onSelectChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
8859
const version = event.target.value;
@@ -91,40 +62,108 @@ export class ListItemRenderer<T extends ArduinoComponent> {
9162
}
9263
};
9364

94-
const versions = (() => {
95-
const { availableVersions } = item;
96-
if (availableVersions.length === 0) {
97-
return undefined;
98-
} else if (availableVersions.length === 1) {
99-
return <label>{availableVersions[0]}</label>;
100-
} else {
101-
return (
102-
<select
103-
className="theia-select"
104-
value={input.selectedVersion}
105-
onChange={onSelectChange}
106-
>
107-
{item.availableVersions
108-
.filter((version) => version !== item.installedVersion) // Filter the version that is currently installed.
109-
.map((version) => (
110-
<option value={version} key={version}>
111-
{version}
112-
</option>
113-
))}
114-
</select>
115-
);
65+
const actionType = itemAction({
66+
installed: installedVersion,
67+
available: availableVersions,
68+
selected: selectedVersion,
69+
});
70+
71+
let installButton: JSX.Element | undefined;
72+
if (!input.state) {
73+
switch (actionType) {
74+
case 'installLatest': {
75+
installButton = (
76+
<button
77+
className="theia-button primary install uppercase"
78+
onClick={() => install(item)}
79+
>
80+
{nls.localize('arduino/component/install', 'Install')}
81+
</button>
82+
);
83+
break;
84+
}
85+
case 'installSelected': {
86+
installButton = (
87+
<button
88+
className="theia-button secondary install uppercase"
89+
onClick={() => install(item)}
90+
>
91+
{nls.localize('arduino/component/install', 'Install')}
92+
</button>
93+
);
94+
break;
95+
}
96+
case 'update': {
97+
installButton = (
98+
<button
99+
className="theia-button secondary install uppercase"
100+
onClick={() => install(item)}
101+
>
102+
{nls.localize('arduino/component/update', 'Update')}
103+
</button>
104+
);
105+
break;
106+
}
107+
case 'remove': {
108+
installButton = (
109+
<button
110+
className="theia-button secondary install uppercase"
111+
onClick={() => uninstall(item)}
112+
>
113+
{nls.localize('arduino/component/remove', 'Remove')}
114+
</button>
115+
);
116+
break;
117+
}
118+
case 'unknown': {
119+
// NOOP
120+
break;
121+
}
116122
}
117-
})();
123+
}
124+
125+
const versions = actionType !== 'unknown' && (
126+
<select
127+
className="theia-select"
128+
value={input.selectedVersion}
129+
onChange={onSelectChange}
130+
>
131+
{item.availableVersions.map((version) => (
132+
<option value={version} key={version}>
133+
{version}
134+
</option>
135+
))}
136+
</select>
137+
);
118138

119139
return (
120140
<div className="component-list-item noselect">
121141
<div className="header">
122142
{nameAndAuthor}
123-
{installedVersion}
143+
{installedVersion && (
144+
<div className="version-info">
145+
<span
146+
className="installed"
147+
onClick={() => uninstall(item)}
148+
{...{
149+
install: nls.localize(
150+
'arduino/component/installed',
151+
'{0} installed',
152+
installedVersion
153+
),
154+
uninstall: nls.localize(
155+
'arduino/component/uninstall',
156+
'Uninstall'
157+
),
158+
}}
159+
/>
160+
</div>
161+
)}
124162
</div>
125163
<div className="content">
126-
{summary}
127-
{description}
164+
<div className="summary">
165+
{[item.summary, item.description].filter(Boolean).join(' ')}
166+
</div>
128167
</div>
129168
<div className="info">{moreInfo}</div>
130169
<div className="footer">
Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,35 @@
1-
import { Installable } from './installable';
1+
import type { Installable } from './installable';
22

33
export interface ArduinoComponent {
44
readonly name: string;
5-
readonly deprecated?: boolean;
65
readonly author: string;
76
readonly summary: string;
87
readonly description: string;
9-
readonly moreInfoLink?: string;
108
readonly availableVersions: Installable.Version[];
11-
readonly installable: boolean;
129
readonly installedVersion?: Installable.Version;
1310
/**
1411
* This is the `Type` in IDE (1.x) UI.
1512
*/
1613
readonly types: string[];
14+
readonly deprecated?: boolean;
15+
readonly moreInfoLink?: string;
1716
}
1817
export namespace ArduinoComponent {
19-
export function is(arg: any): arg is ArduinoComponent {
18+
export function is(arg: unknown): arg is ArduinoComponent {
2019
return (
21-
!!arg &&
22-
'name' in arg &&
23-
typeof arg['name'] === 'string' &&
24-
'author' in arg &&
25-
typeof arg['author'] === 'string' &&
26-
'summary' in arg &&
27-
typeof arg['summary'] === 'string' &&
28-
'description' in arg &&
29-
typeof arg['description'] === 'string' &&
30-
'installable' in arg &&
31-
typeof arg['installable'] === 'boolean'
20+
typeof arg === 'object' &&
21+
(<ArduinoComponent>arg).name !== undefined &&
22+
typeof (<ArduinoComponent>arg).name === 'string' &&
23+
(<ArduinoComponent>arg).author !== undefined &&
24+
typeof (<ArduinoComponent>arg).author === 'string' &&
25+
(<ArduinoComponent>arg).summary !== undefined &&
26+
typeof (<ArduinoComponent>arg).summary === 'string' &&
27+
(<ArduinoComponent>arg).description !== undefined &&
28+
typeof (<ArduinoComponent>arg).description === 'string' &&
29+
(<ArduinoComponent>arg).availableVersions !== undefined &&
30+
Array.isArray((<ArduinoComponent>arg).availableVersions) &&
31+
(<ArduinoComponent>arg).types !== undefined &&
32+
Array.isArray((<ArduinoComponent>arg).types)
3233
);
3334
}
3435
}

‎arduino-ide-extension/src/common/protocol/installable.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ export namespace Installable {
5151
};
5252
}
5353

54+
export function latest(versions: Version[]): Version | undefined {
55+
if (!versions.length) {
56+
return undefined;
57+
}
58+
const ordered = versions.slice().sort(Installable.Version.COMPARATOR);
59+
return ordered[ordered.length - 1];
60+
}
61+
5462
export const Installed = <T extends ArduinoComponent>({
5563
installedVersion,
5664
}: T): boolean => {

‎arduino-ide-extension/src/node/library-service-impl.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ export class LibraryServiceImpl
103103
return toLibrary(
104104
{
105105
name: item.getName(),
106-
installable: true,
107106
installedVersion,
108107
},
109108
item.getLatest()!,
@@ -219,7 +218,6 @@ export class LibraryServiceImpl
219218
{
220219
name: library.getName(),
221220
installedVersion,
222-
installable: true,
223221
description: library.getSentence(),
224222
summary: library.getParagraph(),
225223
moreInfoLink: library.getWebsite(),
@@ -455,8 +453,7 @@ function toLibrary(
455453
return {
456454
name: '',
457455
exampleUris: [],
458-
installable: false,
459-
location: 0,
456+
location: LibraryLocation.BUILTIN,
460457
...pkg,
461458

462459
author: lib.getAuthor(),

‎arduino-ide-extension/src/test/browser/fixtures/boards.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ export const aPackage: BoardsPackage = {
4949
deprecated: false,
5050
description: 'Some Arduino Board, Some Other Arduino Board',
5151
id: 'some:arduinoCoreId',
52-
installable: true,
5352
moreInfoLink: 'http://www.some-url.lol/',
5453
name: 'Some Arduino Package',
5554
summary: 'Boards included in this package:',
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { expect } from 'chai';
2+
import {
3+
itemAction,
4+
ItemActionType,
5+
} from '../../browser/widgets/component-list/item-action';
6+
import type { Installable } from '../../common/protocol';
7+
8+
describe('item-action', () => {
9+
describe('itemAction', () => {
10+
const installLatest: ItemActionType = 'installLatest';
11+
const installSelected: ItemActionType = 'installSelected';
12+
const update: ItemActionType = 'update';
13+
const remove: ItemActionType = 'remove';
14+
const unknown: ItemActionType = 'unknown';
15+
const notAvailable = '0.0.0';
16+
const latest = '2.0.0';
17+
// shuffled versions
18+
const available: Installable.Version[] = [
19+
'1.4.1',
20+
'1.0.0',
21+
latest,
22+
'2.0.0-beta.1',
23+
'1.5',
24+
];
25+
26+
it("should result 'unknown' if available is empty", () => {
27+
expect(itemAction({ available: [] })).to.be.equal(unknown);
28+
});
29+
it("should result 'unknown' if installed is not in available", () => {
30+
expect(itemAction({ available, installed: notAvailable })).to.be.equal(
31+
unknown
32+
);
33+
});
34+
35+
it("should result 'installLatest' if not installed and not selected", () => {
36+
expect(itemAction({ available })).to.be.equal(installLatest);
37+
});
38+
it("should result 'installLatest' if not installed and latest is selected", () => {
39+
expect(itemAction({ available, selected: latest })).to.be.equal(
40+
installLatest
41+
);
42+
});
43+
44+
it("should result 'installSelected' if not installed and not latest is selected", () => {
45+
available
46+
.filter((version) => version !== latest)
47+
.forEach((selected) =>
48+
expect(
49+
itemAction({
50+
available,
51+
selected,
52+
})
53+
).to.be.equal(installSelected)
54+
);
55+
});
56+
it("should result 'installSelected' if installed and the selected is neither the latest nor the installed", () => {
57+
available.forEach((installed) =>
58+
available
59+
.filter((selected) => selected !== latest && selected !== installed)
60+
.forEach((selected) =>
61+
expect(
62+
itemAction({
63+
installed,
64+
available,
65+
selected,
66+
})
67+
).to.be.equal(installSelected)
68+
)
69+
);
70+
});
71+
72+
it("should result 'update' if the installed version is not the latest and the latest is selected", () => {
73+
available
74+
.filter((installed) => installed !== latest)
75+
.forEach((installed) =>
76+
expect(
77+
itemAction({
78+
installed,
79+
available,
80+
selected: latest,
81+
})
82+
).to.be.equal(update)
83+
);
84+
});
85+
86+
it("should result 'remove' if the selected version equals the installed version", () => {
87+
available.forEach((version) =>
88+
expect(
89+
itemAction({
90+
installed: version,
91+
available,
92+
selected: version,
93+
})
94+
).to.be.equal(remove)
95+
);
96+
});
97+
});
98+
});

‎package.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@
3636
"typescript": "~4.5.5",
3737
"xhr2": "^0.2.1"
3838
},
39-
"resolutions": {
40-
"@types/react": "18.0.0",
41-
"@types/react-dom": "18.0.0"
42-
},
4339
"scripts": {
4440
"prepare": "lerna run prepare && yarn download:plugins",
4541
"cleanup": "npx rimraf ./**/node_modules && rm -rf ./node_modules ./.browser_modules ./arduino-ide-extension/build ./arduino-ide-extension/downloads ./arduino-ide-extension/Examples ./arduino-ide-extension/lib ./electron-app/lib ./electron-app/src-gen ./electron-app/gen-webpack.config.js",

‎yarn.lock

Lines changed: 16 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -898,13 +898,6 @@
898898
dependencies:
899899
regenerator-runtime "^0.13.10"
900900

901-
"@babel/runtime@^7.7.2":
902-
version "7.20.1"
903-
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.1.tgz#1148bb33ab252b165a06698fde7576092a78b4a9"
904-
integrity sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==
905-
dependencies:
906-
regenerator-runtime "^0.13.10"
907-
908901
"@babel/template@^7.18.6":
909902
version "7.18.6"
910903
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31"
@@ -3535,10 +3528,10 @@
35353528
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc"
35363529
integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
35373530

3538-
"@types/react-dom@18.0.0", "@types/react-dom@^18.0.6":
3539-
version "18.0.0"
3540-
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.0.tgz#b13f8d098e4b0c45df4f1ed123833143b0c71141"
3541-
integrity sha512-49897Y0UiCGmxZqpC8Blrf6meL8QUla6eb+BBhn69dTXlmuOlzkfr7HHY/O8J25e1lTUMs+YYxSlVDAaGHCOLg==
3531+
"@types/react-dom@^18.0.6":
3532+
version "18.0.11"
3533+
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.11.tgz#321351c1459bc9ca3d216aefc8a167beec334e33"
3534+
integrity sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==
35423535
dependencies:
35433536
"@types/react" "*"
35443537

@@ -3556,22 +3549,14 @@
35563549
dependencies:
35573550
"@types/react" "*"
35583551

3559-
"@types/react-virtualized@^9.21.21":
3560-
version "9.21.21"
3561-
resolved "https://registry.yarnpkg.com/@types/react-virtualized/-/react-virtualized-9.21.21.tgz#65c96f25314f0fb3d40536929dc78112753b49e1"
3562-
integrity sha512-Exx6I7p4Qn+BBA1SRyj/UwQlZ0I0Pq7g7uhAp0QQ4JWzZunqEqNBGTmCmMmS/3N9wFgAGWuBD16ap7k8Y14VPA==
3563-
dependencies:
3564-
"@types/prop-types" "*"
3565-
"@types/react" "^17"
3566-
35673552
"@types/react-window@^1.8.5":
35683553
version "1.8.5"
35693554
resolved "https://registry.yarnpkg.com/@types/react-window/-/react-window-1.8.5.tgz#285fcc5cea703eef78d90f499e1457e9b5c02fc1"
35703555
integrity sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==
35713556
dependencies:
35723557
"@types/react" "*"
35733558

3574-
"@types/react@*", "@types/react@18.0.0", "@types/react@^17", "@types/react@^18.0.15":
3559+
"@types/react@*":
35753560
version "18.0.0"
35763561
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.0.tgz#4be8aa3a2d04afc3ac2cc1ca43d39b0bd412890c"
35773562
integrity sha512-7+K7zEQYu7NzOwQGLR91KwWXXDzmTFODRVizJyIALf6RfLv2GDpqpknX64pvRVILXCpXi7O/pua8NGk44dLvJw==
@@ -3580,6 +3565,15 @@
35803565
"@types/scheduler" "*"
35813566
csstype "^3.0.2"
35823567

3568+
"@types/react@^18.0.15":
3569+
version "18.0.28"
3570+
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.28.tgz#accaeb8b86f4908057ad629a26635fe641480065"
3571+
integrity sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==
3572+
dependencies:
3573+
"@types/prop-types" "*"
3574+
"@types/scheduler" "*"
3575+
csstype "^3.0.2"
3576+
35833577
"@types/request@^2.0.3":
35843578
version "2.48.8"
35853579
resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.8.tgz#0b90fde3b655ab50976cb8c5ac00faca22f5a82c"
@@ -5542,7 +5536,7 @@ cloneable-readable@^1.0.0:
55425536
process-nextick-args "^2.0.0"
55435537
readable-stream "^2.3.5"
55445538

5545-
clsx@^1.0.4, clsx@^1.1.0:
5539+
clsx@^1.1.0:
55465540
version "1.2.1"
55475541
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
55485542
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
@@ -6436,7 +6430,7 @@ doctrine@^3.0.0:
64366430
dependencies:
64376431
esutils "^2.0.2"
64386432

6439-
dom-helpers@^5.0.1, dom-helpers@^5.1.3:
6433+
dom-helpers@^5.0.1:
64406434
version "5.2.1"
64416435
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
64426436
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
@@ -12322,11 +12316,6 @@ react-is@^18.0.0:
1232212316
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
1232312317
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
1232412318

12325-
react-lifecycles-compat@^3.0.4:
12326-
version "3.0.4"
12327-
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
12328-
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
12329-
1233012319
react-markdown@^8.0.0:
1233112320
version "8.0.3"
1233212321
resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-8.0.3.tgz#e8aba0d2f5a1b2124d476ee1fff9448a2f57e4b3"
@@ -12397,18 +12386,6 @@ react-transition-group@^4.3.0:
1239712386
loose-envify "^1.4.0"
1239812387
prop-types "^15.6.2"
1239912388

12400-
react-virtualized@^9.22.3:
12401-
version "9.22.3"
12402-
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.3.tgz#f430f16beb0a42db420dbd4d340403c0de334421"
12403-
integrity sha512-MKovKMxWTcwPSxE1kK1HcheQTWfuCxAuBoSTf2gwyMM21NdX/PXUhnoP8Uc5dRKd+nKm8v41R36OellhdCpkrw==
12404-
dependencies:
12405-
"@babel/runtime" "^7.7.2"
12406-
clsx "^1.0.4"
12407-
dom-helpers "^5.1.3"
12408-
loose-envify "^1.4.0"
12409-
prop-types "^15.7.2"
12410-
react-lifecycles-compat "^3.0.4"
12411-
1241212389
react-virtuoso@^2.17.0:
1241312390
version "2.19.1"
1241412391
resolved "https://registry.yarnpkg.com/react-virtuoso/-/react-virtuoso-2.19.1.tgz#a660a5c3cafcc7a84b59dfc356e1916e632c1e3a"

0 commit comments

Comments
 (0)
Please sign in to comment.