mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-11-19 07:09:28 +00:00
PROEDITOR-7: Cloned the Library Manager layout.
To match with the official Arduino editor's UI. Signed-off-by: Akos Kitta <kittaakos@typefox.io>
This commit is contained in:
@@ -4,7 +4,7 @@ import { ArduinoComponent } from '../../../common/protocol/arduino-component';
|
||||
|
||||
export class ComponentListItem extends React.Component<ComponentListItem.Props> {
|
||||
|
||||
private onClick = (event: React.SyntheticEvent<HTMLAnchorElement, Event>) => {
|
||||
protected onClick = (event: React.SyntheticEvent<HTMLAnchorElement, Event>) => {
|
||||
const { target } = event.nativeEvent;
|
||||
if (target instanceof HTMLAnchorElement) {
|
||||
this.props.windowService.openNewWindow(target.href);
|
||||
@@ -12,7 +12,7 @@ export class ComponentListItem extends React.Component<ComponentListItem.Props>
|
||||
}
|
||||
}
|
||||
|
||||
private async install(item: ArduinoComponent) {
|
||||
protected async install(item: ArduinoComponent): Promise<void> {
|
||||
await this.props.install(item);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,26 @@ import { ArduinoComponent } from '../../../common/protocol/arduino-component';
|
||||
|
||||
export class ComponentList extends React.Component<ComponentList.Props> {
|
||||
|
||||
protected container?: HTMLElement;
|
||||
|
||||
render(): React.ReactNode {
|
||||
return <div>
|
||||
{this.props.items.map(item => <ComponentListItem key={item.name} item={item} windowService={this.props.windowService} install={this.props.install} />)}
|
||||
return <div
|
||||
className={'items-container'}
|
||||
ref={element => this.container = element || undefined}>
|
||||
{this.props.items.map(item => this.createItem(item))}
|
||||
</div>;
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
if (this.container && this.props.resolveContainer) {
|
||||
this.props.resolveContainer(this.container);
|
||||
}
|
||||
}
|
||||
|
||||
protected createItem(item: ArduinoComponent): React.ReactNode {
|
||||
return <ComponentListItem key={item.name} item={item} windowService={this.props.windowService} install={this.props.install} />
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export namespace ComponentList {
|
||||
@@ -19,6 +33,7 @@ export namespace ComponentList {
|
||||
readonly items: ArduinoComponent[];
|
||||
readonly windowService: WindowService;
|
||||
readonly install: (comp: ArduinoComponent) => Promise<void>;
|
||||
readonly resolveContainer?: (element: HTMLElement) => void;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
||||
import { ComponentList } from './component-list';
|
||||
import { SearchBar } from './search-bar';
|
||||
import { ComponentList } from './component-list';
|
||||
import { LibraryService } from '../../../common/protocol/library-service';
|
||||
import { ArduinoComponent } from '../../../common/protocol/arduino-component';
|
||||
import { InstallationProgressDialog } from '../installation-progress-dialog';
|
||||
|
||||
@@ -21,21 +22,37 @@ export class FilterableListContainer extends React.Component<FilterableListConta
|
||||
}
|
||||
|
||||
render(): React.ReactNode {
|
||||
return <div className={FilterableListContainer.Styles.FILTERABLE_LIST_CONTAINER_CLASS}>
|
||||
<SearchBar
|
||||
filterText={this.state.filterText}
|
||||
onFilterTextChanged={this.handleFilterTextChange}
|
||||
/>
|
||||
<ComponentList
|
||||
items={this.state.items}
|
||||
install={this.install.bind(this)}
|
||||
windowService={this.props.windowService}
|
||||
/>
|
||||
return <div className={'filterable-list-container'}>
|
||||
{this.renderSearchFilter()}
|
||||
{this.renderSearchBar()}
|
||||
{this.renderComponentList()}
|
||||
</div>
|
||||
}
|
||||
|
||||
protected renderSearchFilter(): React.ReactNode {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
protected renderSearchBar(): React.ReactNode {
|
||||
return <SearchBar
|
||||
resolveFocus={this.props.resolveFocus}
|
||||
filterText={this.state.filterText}
|
||||
onFilterTextChanged={this.handleFilterTextChange}
|
||||
/>
|
||||
}
|
||||
|
||||
protected renderComponentList(): React.ReactNode {
|
||||
return <ComponentList
|
||||
items={this.state.items}
|
||||
install={this.install.bind(this)}
|
||||
windowService={this.props.windowService}
|
||||
resolveContainer={this.props.resolveContainer}
|
||||
/>
|
||||
}
|
||||
|
||||
private handleFilterTextChange(filterText: string): void {
|
||||
this.props.service.search({ query: filterText }).then(result => {
|
||||
const { props } = this.state;
|
||||
this.props.service.search({ query: filterText, props }).then(result => {
|
||||
const { items } = result;
|
||||
this.setState({
|
||||
filterText,
|
||||
@@ -45,15 +62,7 @@ export class FilterableListContainer extends React.Component<FilterableListConta
|
||||
}
|
||||
|
||||
protected sort(items: ArduinoComponent[]): ArduinoComponent[] {
|
||||
return items.sort((a, b) => {
|
||||
if (a.name < b.name) {
|
||||
return -1;
|
||||
} else if (a.name === b.name) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
return items.sort((left, right) => left.name.localeCompare(right.name));
|
||||
}
|
||||
|
||||
protected async install(comp: ArduinoComponent): Promise<void> {
|
||||
@@ -61,7 +70,8 @@ export class FilterableListContainer extends React.Component<FilterableListConta
|
||||
dialog.open();
|
||||
try {
|
||||
await this.props.service.install(comp);
|
||||
const { items } = await this.props.service.search({ query: this.state.filterText });
|
||||
const { props } = this.state;
|
||||
const { items } = await this.props.service.search({ query: this.state.filterText, props });
|
||||
this.setState({ items: this.sort(items) });
|
||||
} finally {
|
||||
dialog.close();
|
||||
@@ -75,19 +85,18 @@ export namespace FilterableListContainer {
|
||||
export interface Props {
|
||||
readonly service: ComponentSource;
|
||||
readonly windowService: WindowService;
|
||||
readonly resolveContainer?: (element: HTMLElement) => void;
|
||||
readonly resolveFocus?: (element: HTMLElement | undefined) => void;
|
||||
}
|
||||
|
||||
export interface State {
|
||||
filterText: string;
|
||||
items: ArduinoComponent[];
|
||||
}
|
||||
|
||||
export namespace Styles {
|
||||
export const FILTERABLE_LIST_CONTAINER_CLASS = 'filterable-list-container';
|
||||
props?: LibraryService.Search.Props;
|
||||
}
|
||||
|
||||
export interface ComponentSource {
|
||||
search(req: { query: string }): Promise<{ items: ArduinoComponent[] }>
|
||||
search(req: { query: string, props?: LibraryService.Search.Props }): Promise<{ items: ArduinoComponent[] }>
|
||||
install(board: ArduinoComponent): Promise<void>;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,15 +9,22 @@ export class SearchBar extends React.Component<SearchBar.Props> {
|
||||
|
||||
render(): React.ReactNode {
|
||||
return <input
|
||||
ref={this.setRef}
|
||||
className={SearchBar.Styles.SEARCH_BAR_CLASS}
|
||||
type='text'
|
||||
placeholder='Search'
|
||||
placeholder='Filter your search...'
|
||||
size={1}
|
||||
value={this.props.filterText}
|
||||
onChange={this.handleFilterTextChange}
|
||||
/>;
|
||||
}
|
||||
|
||||
private setRef = (element: HTMLElement | null) => {
|
||||
if (this.props.resolveFocus) {
|
||||
this.props.resolveFocus(element || undefined);
|
||||
}
|
||||
}
|
||||
|
||||
private handleFilterTextChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
this.props.onFilterTextChanged(event.target.value);
|
||||
}
|
||||
@@ -29,6 +36,7 @@ export namespace SearchBar {
|
||||
export interface Props {
|
||||
filterText: string;
|
||||
onFilterTextChanged(filterText: string): void;
|
||||
readonly resolveFocus?: (element: HTMLElement | undefined) => void;
|
||||
}
|
||||
|
||||
export namespace Styles {
|
||||
|
||||
Reference in New Issue
Block a user