Skip to content
This repository was archived by the owner on Jul 3, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/client/components/dropdown/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

.dropdownMenu {
position: absolute;
top: 100%;
z-index: 1;
}

Expand All @@ -15,3 +14,11 @@
.dropdownMenuRight {
right: 0;
}

.dropdownMenuUp {
bottom: 100%;
}

.dropdownMenuDown {
top: 100%;
}
4 changes: 3 additions & 1 deletion src/client/components/dropdown/view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ export interface DropdownProps {
isOpen: boolean
isFullwidth?: boolean
dropdownPosition?: 'left' | 'right'
dropDirection?: 'up' | 'down'
onRef?(dropdown: HTMLDivElement): void
onToggleClick?(event: MouseEvent<HTMLSpanElement>): void
}

export const Dropdown: StatelessComponent<DropdownProps> = (props: DropdownProps) => {
const fullwidth = props.isFullwidth ? style.dropdownMenuFullwidth : ''
const position = props.dropdownPosition === 'right' ? style.dropdownMenuRight : ''
const dropdownMenuClassName = classNames(style.dropdownMenu, fullwidth, position)
const direction = props.dropDirection === 'up' ? style.dropdownMenuUp : style.dropdownMenuDown
const dropdownMenuClassName = classNames(style.dropdownMenu, fullwidth, position, direction)

return (
<div className={classNames([style.dropdown, props.className])} ref={props.onRef}>
Expand Down
3 changes: 3 additions & 0 deletions src/client/components/robot_selector_single/plug.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/client/components/robot_selector_single/robot.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { action } from '@storybook/addon-actions'
import { storiesOf } from '@storybook/react'
import { action as mobxAction, observable } from 'mobx'
import { observer } from 'mobx-react'
import * as React from 'react'

import { RobotModel } from '../../robot/model'
import { RobotSelectorSingle } from '../view'

const actions = {
onSelect: action('onSelect'),
}

storiesOf('components.robot_selector_single', module)
.addDecorator(story => <div style={{ maxWidth: '320px' }}>{story()}</div>)
.add('renders empty', () => {
return <RobotSelectorSingle
robots={[]}
onSelect={actions.onSelect}
/>
})
.add('renders with robots', () => {
const robots = getRobots()
return <RobotSelectorSingle
robots={robots}
onSelect={actions.onSelect}
/>
})
.add('renders with selection', () => {
const robots = getRobots()
const selected = robots[0]
return <RobotSelectorSingle
robots={robots}
selected={selected}
onSelect={actions.onSelect}
/>
})
.add('interactive', () => {
const robots = getRobots()
const model = observable({
robots,
selected: robots[1],
})
const onSelect = mobxAction((robot: RobotModel) => model.selected = robot)
const Component = observer(() => <RobotSelectorSingle
robots={model.robots}
selected={model.selected}
onSelect={onSelect}
/>)
return <Component/>
})

function getRobots(): RobotModel[] {
return [
{
id: '1',
name: 'Virtual Robot 1',
connected: true,
enabled: true,
address: '',
port: 0,
},
{
id: '2',
name: 'Virtual Robot 2',
connected: true,
enabled: true,
address: '',
port: 0,
},
{
id: '3',
name: 'Virtual Robot 3',
connected: true,
enabled: true,
address: '',
port: 0,
},
]
}
30 changes: 30 additions & 0 deletions src/client/components/robot_selector_single/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.empty {
color: #888;
padding: 1em;
text-align: center;
}

.emptyIcon {
background-color: #888;
border-radius: 100%;
box-shadow:
0 0 8px 0 rgba(0, 0, 0, 0.2),
1px 1px 4px 0 rgba(0,0,0,0.2);
fill: #fff;
height: 3em;
margin: 0 auto 1em auto;
opacity: 0.8;
padding: 1em;
width: 3em;
}

.emptyTitle {
font-size: 1.54em;
padding: 0.25em 0;
white-space: nowrap;
}

.emptyDescription {
font-size: 0.93em;
white-space: nowrap;
}
67 changes: 67 additions & 0 deletions src/client/components/robot_selector_single/view.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { computed } from 'mobx'
import { observer } from 'mobx-react'
import * as React from 'react'

import { RobotModel } from '../robot/model'
import { Option, Select } from '../select/view'

import PlugIcon from './plug.svg'
import RobotIcon from './robot.svg'
import * as style from './style.css'

export type RobotSelectorSingleProps = {
robots: RobotModel[]
selected?: RobotModel
dropDirection?: 'up' | 'down'
onSelect(robot: RobotModel): void
}

@observer
export class RobotSelectorSingle extends React.Component<RobotSelectorSingleProps> {
render() {
const { dropDirection } = this.props
return <div className={style.robotSelector}>
<Select
options={this.options}
selectedOption={this.selectedOption}
onChange={this.onChange}
placeholder='Select a robot...'
empty={this.renderEmpty}
icon={<RobotIcon/>}
dropDirection={dropDirection}
/>
</div>
}

@computed
private get renderEmpty() {
return <div className={style.empty}>
<div className={style.emptyIcon}><PlugIcon/></div>
<div className={style.emptyTitle}>No connected robots</div>
<span className={style.emptyDescription}>Run yarn start:sim to simulate robots</span>
</div>
}

@computed
private get options() {
return this.props.robots.map(robot => ({
id: robot.id,
label: robot.name,
robot,
}))
}

@computed
private get selectedOption() {
if (this.props.selected) {
return {
id: this.props.selected.id,
label: this.props.selected.name,
}
}
}

private onChange = (option: Option) => {
this.props.onSelect(this.props.robots.find(robot => robot.id === option.id)!)
}
}
4 changes: 3 additions & 1 deletion src/client/components/select/view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export type SelectProps = {
selectedOption?: Option
icon?: ReactNode
empty?: ReactNode
dropDirection?: 'up' | 'down'
onChange(option: Option): void
}

Expand All @@ -48,7 +49,7 @@ export class Select extends React.Component<SelectProps> {
}

render(): JSX.Element {
const { className, icon, placeholder, empty, options, selectedOption } = this.props
const { className, icon, placeholder, dropDirection, empty, options, selectedOption } = this.props

const button = (
<Button
Expand All @@ -64,6 +65,7 @@ export class Select extends React.Component<SelectProps> {
<Dropdown
className={className}
dropdownToggle={button}
dropDirection={dropDirection}
isOpen={this.isOpen}
isFullwidth={true}
onToggleClick={this.onToggleClick}
Expand Down