Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from markerikson/practical-redux-part-10-final
Practical Redux Part 10 - final
- Loading branch information
Showing
40 changed files
with
619 additions
and
17 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import React from "react"; | ||
import PropTypes from "prop-types"; | ||
|
||
const AbsolutePosition = (props) => { | ||
const {children, nodeRef} = props; | ||
const style = { | ||
position: 'absolute', | ||
top: props.top, | ||
bottom : props.bottom, | ||
left: props.left, | ||
right : props.right, | ||
width: props.width, | ||
}; | ||
|
||
|
||
return ( | ||
<div style={style} className={props.className} ref={nodeRef}> | ||
{children} | ||
</div> | ||
); | ||
} | ||
|
||
AbsolutePosition.propTypes = { | ||
top: PropTypes.number, | ||
bottom : PropTypes.number, | ||
left: PropTypes.number, | ||
width: PropTypes.number, | ||
nodeRef : PropTypes.func, | ||
}; | ||
|
||
export default AbsolutePosition; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import React from "react"; | ||
|
||
import {Button} from "semantic-ui-react"; | ||
|
||
const ColorPickerButton = ({value, onClick, disabled=false}) => { | ||
return ( | ||
<Button | ||
type="button" | ||
style={{padding: "4px", margin: 0}} | ||
disabled={disabled} | ||
onClick={onClick} | ||
> | ||
<div | ||
style={{ | ||
width : 30, | ||
height : 15, | ||
backgroundColor : value | ||
}} | ||
/> | ||
</Button> | ||
) | ||
} | ||
|
||
export default ColorPickerButton; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import React, {Component} from "react"; | ||
import {connect} from "react-redux"; | ||
import { | ||
Modal, | ||
Button, | ||
} from "semantic-ui-react"; | ||
|
||
import {SketchPicker} from "react-color"; | ||
|
||
import {closeModal} from "features/modals/modalActions"; | ||
import {colorSelected} from "./colorPickerActions"; | ||
|
||
const actions = {closeModal, colorSelected}; | ||
|
||
export class ColorPickerDialog extends Component { | ||
constructor(props) { | ||
super(); | ||
this.state = { | ||
color : props.color | ||
} | ||
} | ||
|
||
onSelectClicked = () => { | ||
this.props.colorSelected(this.state.color, this.props.onColorPicked); | ||
|
||
this.props.closeModal(); | ||
} | ||
|
||
onSelectedColorChanged = (colorEvent) => { | ||
this.setState({color : colorEvent.hex}); | ||
} | ||
|
||
render() { | ||
const {closeModal} = this.props; | ||
|
||
return ( | ||
<Modal | ||
closeIcon="close" | ||
open={true} | ||
onClose={closeModal} | ||
size="small" | ||
> | ||
<Modal.Header>Select Color</Modal.Header> | ||
<Modal.Content> | ||
<SketchPicker | ||
color={this.state.color} | ||
onChangeComplete={this.onSelectedColorChanged} | ||
/> | ||
</Modal.Content> | ||
<Modal.Actions> | ||
<Button positive onClick={this.onSelectClicked}>Select</Button> | ||
<Button secondary onClick={closeModal}>Cancel</Button> | ||
</Modal.Actions> | ||
</Modal> | ||
) | ||
} | ||
} | ||
|
||
ColorPickerDialog.defaultProps = { | ||
color : "red" | ||
}; | ||
|
||
|
||
export default connect(null, actions)(ColorPickerDialog); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import _ from "lodash"; | ||
|
||
import { | ||
openModal | ||
} from "features/modals/modalActions"; | ||
|
||
export function showColorPicker(initialColor, onColorPickedAction) { | ||
// Define props that we want to "pass" to the ColorPicker dialog, | ||
// including the body of the action that should be dispatched when | ||
// the dialog is actually used to select a color. | ||
const colorPickerProps = { | ||
color : initialColor, | ||
onColorPicked : onColorPickedAction | ||
}; | ||
return openModal("ColorPickerDialog", colorPickerProps); | ||
} | ||
|
||
export function colorSelected(color, actionToDispatch) { | ||
return (dispatch) => { | ||
if(actionToDispatch) { | ||
const newAction = _.cloneDeep(actionToDispatch); | ||
newAction.payload.color = color; | ||
|
||
dispatch(newAction); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,4 +16,6 @@ export function getValueFromEvent(e) { | |
} | ||
|
||
return newValues; | ||
} | ||
} | ||
|
||
export const noop = () => {}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import React, {Component} from "react"; | ||
import {connect} from "react-redux"; | ||
|
||
import AbsolutePosition from "common/components/AbsolutePosition"; | ||
|
||
import {hideContextMenu} from "./contextMenuActions"; | ||
|
||
const actions = {hideContextMenu}; | ||
|
||
export class ContextMenu extends Component { | ||
|
||
componentDidMount() { | ||
document.addEventListener('click', this.handleClickOutside, true); | ||
} | ||
|
||
componentWillUnmount() { | ||
document.removeEventListener('click', this.handleClickOutside, true); | ||
} | ||
|
||
handleClickOutside = (e) => { | ||
if (!this.node || !this.node.contains(e.target) ) { | ||
this.props.hideContextMenu(); | ||
} | ||
} | ||
|
||
render() { | ||
const {location} = this.props; | ||
|
||
return ( | ||
<AbsolutePosition | ||
left={location.x + 2} | ||
top={location.y} | ||
className="contextMenu" | ||
nodeRef={node => this.node = node} | ||
> | ||
{this.props.children} | ||
</AbsolutePosition> | ||
) | ||
} | ||
} | ||
|
||
export default connect(null, actions)(ContextMenu); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import React, {Component} from "react"; | ||
import {connect} from "react-redux"; | ||
import Portal from 'react-portal'; | ||
|
||
import ContextMenu from "./ContextMenu"; | ||
|
||
import TestContextMenu from "./TestContextMenu"; | ||
import PilotsListItemMenu from "features/pilots/PilotsList/PilotsListItemMenu"; | ||
|
||
import {selectContextMenu} from "./contextMenuSelectors"; | ||
|
||
const menuTypes = { | ||
TestContextMenu, | ||
PilotsListItemMenu | ||
}; | ||
|
||
|
||
export function contextMenuManagerMapState(state) { | ||
return { | ||
contextMenu : selectContextMenu(state) | ||
}; | ||
} | ||
|
||
|
||
export class ContextMenuManager extends Component { | ||
|
||
render() { | ||
const {contextMenu} = this.props; | ||
const {show, location, type, menuArgs = {}} = contextMenu; | ||
|
||
let menu = null; | ||
|
||
if(show) { | ||
let MenuComponent = menuTypes[type]; | ||
|
||
if(MenuComponent) { | ||
menu = ( | ||
<Portal isOpened={true}> | ||
<ContextMenu location={location}> | ||
<MenuComponent {...menuArgs} /> | ||
</ContextMenu> | ||
</Portal> | ||
) | ||
} | ||
} | ||
|
||
return menu; | ||
} | ||
} | ||
|
||
export default connect(contextMenuManagerMapState)(ContextMenuManager); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import React, { Component } from 'react' | ||
import { Menu } from 'semantic-ui-react' | ||
|
||
export default class TestContextMenu extends Component { | ||
render() { | ||
return ( | ||
<Menu vertical> | ||
<Menu.Item> | ||
<Menu.Header>Menu Header: {this.props.text} </Menu.Header> | ||
|
||
<Menu.Menu> | ||
<Menu.Item>First Menu Item</Menu.Item> | ||
<Menu.Item>Second Menu Item</Menu.Item> | ||
</Menu.Menu> | ||
</Menu.Item> | ||
</Menu> | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import {CONTEXT_MENU_HIDE, CONTEXT_MENU_SHOW} from "./contextMenuConstants"; | ||
|
||
|
||
export function showContextMenu(x, y, type, menuArgs) { | ||
return { | ||
type : CONTEXT_MENU_SHOW, | ||
payload : { | ||
location : { | ||
x, | ||
y | ||
}, | ||
type, | ||
menuArgs | ||
} | ||
} | ||
} | ||
|
||
export function hideContextMenu() { | ||
return { | ||
type : CONTEXT_MENU_HIDE | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export const CONTEXT_MENU_SHOW = "CONTEXT_MENU_SHOW"; | ||
export const CONTEXT_MENU_HIDE = "CONTEXT_MENU_HIDE"; |
Oops, something went wrong.