Skip to content

Commit 156c388

Browse files
committed
Merge pull request #50 from kuutamol/master
Help layer
2 parents 66e1ea6 + 263f6a8 commit 156c388

16 files changed

Lines changed: 666 additions & 36 deletions

File tree

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
"react-tween-state": "0.0.4",
2222
"socket.io-client": "1.3.3",
2323
"superagent": "1.1.0",
24-
"utf8": "2.1.0"
24+
"utf8": "2.1.0",
25+
"nuka-carousel": "0.0.12"
2526
},
2627
"devDependencies": {
2728
"babel-eslint": "2.0.2",

src/scripts/components/board-preview.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export default React.createClass({
5050

5151
showDialog(dialog) {
5252
if(!this.props.board.id.startsWith('dirty_')) {
53-
this.setState({[`show${dialog}`]: !this.state[`show${dialog}`]});
53+
this.setState({ [`show${dialog}`]: !this.state[`show${dialog}`] });
5454
}
5555
},
5656

src/scripts/components/dialog/edit-board.js

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,9 @@ export default React.createClass({
4141
id: this.props.board.id,
4242
name: this.state.name,
4343
background: this.state.background,
44-
customBackground: this.state.customBackground,
44+
customBackground: this.state.customBackground
4545
}
4646

47-
4847
if (!isNaN(size.width) && !isNaN(size.height)) {
4948
if (size.width < 1 || size.height < 1) {
5049
size.width = this.props.board.size.width;
@@ -121,11 +120,11 @@ export default React.createClass({
121120
<section className="dialog-size">
122121
<label htmlFor="board-width">Width</label>
123122
<input name="board-width"
124-
placeholder="Board Width"
125-
valueLink={widthValueLink}
126-
type="number"
127-
max="99"
128-
min="1" />
123+
placeholder="Board Width"
124+
valueLink={widthValueLink}
125+
type="number"
126+
max="99"
127+
min="1" />
129128
</section>
130129

131130
<section className="times-wrapper">
@@ -135,13 +134,13 @@ export default React.createClass({
135134
<section className="dialog-size">
136135
<label htmlFor="board-height">Height</label>
137136
<input name="board-height"
138-
placeholder="Board Height"
139-
valueLink={heightValueLink}
140-
type="number"
141-
max="99"
142-
min="1" />
137+
placeholder="Board Height"
138+
valueLink={heightValueLink}
139+
type="number"
140+
max="99"
141+
min="1" />
143142
</section>
144-
</section>
143+
</section>
145144

146145
</section>
147146
<section className="dialog-footer">

src/scripts/components/dialog/index.js

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,19 @@ import Hammer from 'hammerjs';
66
*/
77
export default React.createClass({
88
mixins: [ React.addons.PureRenderMixin ],
9-
9+
//Since this component is used for the infolayer, infoView is true while it
10+
//is active and dictates whether a form gets rendered within the dialog
11+
//or not.
1012
propTypes: {
13+
infoView: React.PropTypes.bool,
1114
className: React.PropTypes.string,
1215
onDismiss: React.PropTypes.func
1316
},
1417

1518
getDefaultProps() {
1619
return {
1720
className: '',
21+
infoView: false,
1822
onDismiss: () => {}
1923
}
2024
},
@@ -58,12 +62,20 @@ export default React.createClass({
5862
},
5963

6064
renderDialog() {
65+
let form = !this.props.infoView ?
66+
<form className={`dialog ${this.props.className}`}
67+
onSubmit={this.onSubmit}>
68+
{this.props.children}
69+
</form> :
70+
<div className={`${this.props.className}`}
71+
onSubmit={this.onSubmit}>
72+
{this.props.children}
73+
</div>
74+
;
75+
6176
return (
6277
<div className="dialog-overlay">
63-
<form className={`dialog ${this.props.className}`}
64-
onSubmit={this.onSubmit}>
65-
{this.props.children}
66-
</form>
78+
{form}
6779
</div>
6880
);
6981
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import React from 'react';
2+
3+
/**
4+
*
5+
*/
6+
// This is the textbox used in the infolayer.
7+
const SingleBox = React.createClass({
8+
propTypes: {
9+
content: React.PropTypes.string,
10+
className: React.PropTypes.string
11+
},
12+
13+
getDefaultProps() {
14+
return {
15+
content: 'Content',
16+
className: ''
17+
}
18+
},
19+
20+
render() {
21+
return (
22+
<div className={`pos ${this.props.className}`}>
23+
<p>{this.props.content}</p>
24+
</div>
25+
);
26+
}
27+
});
28+
29+
// The objects other than textboxes to be shown in the infolayer and
30+
// the instances of SingleBoxes are passed here as props and mapped
31+
export default React.createClass({
32+
propTypes: {
33+
items: React.PropTypes.array,
34+
objects: React.PropTypes.array
35+
},
36+
37+
getDefaultProps() {
38+
return { items: [ ], objects: [ ] }
39+
},
40+
41+
render() {
42+
return (
43+
<div className="infospace">
44+
{this.props.objects}
45+
{this.props.items.map((item, index) => {
46+
return <SingleBox key={index} {...item} />;
47+
})}
48+
</div>
49+
);
50+
}
51+
});
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import React from 'react/addons';
2+
import Carousel from 'nuka-carousel';
3+
import Dialog from '../../components/dialog';
4+
import TextBoxes from './text-box';
5+
import Dropdown from '../dropdown';
6+
7+
/**
8+
*
9+
*/
10+
11+
export default React.createClass({
12+
mixins: [ Carousel.ControllerMixin ],
13+
getInitialState(){
14+
return { currentSlide: null }
15+
},
16+
17+
componentDidMount() {
18+
this.el = document.getElementById('application');
19+
this.el.className = 'info-view-active';
20+
this.avatar = document.getElementById('avatar');
21+
},
22+
23+
componentWillUnmount() {
24+
this.el.className = '';
25+
},
26+
27+
componentDidUpdate(){
28+
this.el.className =
29+
`info-view-active slide-${this.state.carousels.carousel.state.currentSlide}`;
30+
},
31+
32+
render() {
33+
let dropitems = [
34+
{ icon: 'user', content: 'Profile' },
35+
{ icon: 'language', content: 'Localization' },
36+
{ icon: 'bullhorn', content: 'Feedback' },
37+
{ icon: 'sign-out', content: 'Logout' }
38+
];
39+
40+
/*
41+
Second layer arrays represent the slides. First one of the
42+
third layer arrays contain anything other than textbox-components
43+
while the second ones contain the textboxes' props.
44+
*/
45+
let objects = [
46+
[
47+
[ <Dropdown className='infodrop' show={true} items={dropitems} /> ],
48+
[
49+
{ content: 'Return to workspace', className: 'pos-back' },
50+
{ content: 'Edit board', className:'pos-edit' },
51+
{ content: 'Share board', className:'pos-share' },
52+
{ content: 'Export board', className:'pos-export' },
53+
{ content: 'Make tickets snap to grid', className:'pos-magnet' },
54+
{ content: 'Toggle board overview and navigate', className:'pos-minimap' },
55+
{ content: 'Edit your profile', className:'pos-profile' },
56+
{ content: 'Change operating language', className:'pos-localization' },
57+
{ content: 'Send feedback to developers', className:'pos-feedback' },
58+
{ content: 'Logout', className:'pos-logout' }
59+
]
60+
],
61+
[
62+
[ <img draggable="false" className="imgTicket" src="/dist/assets/img/ticket.png"/>,
63+
<img draggable="false" className="imgEditTicket" src="/dist/assets/img/edit-ticket.png"/> ],
64+
[
65+
{ content: 'Double tap board to create a ticket.', className: 'pos-click' },
66+
{ content: 'Double tap a ticket to edit it.', className:'pos-ticket' },
67+
{ content: 'Select a color for your ticket.', className:'pos-color' },
68+
{ content: 'Edit the contents of a ticket.', className:'pos-content' }
69+
]
70+
],
71+
[
72+
[ <img draggable="false" className="imgInfo" src="/dist/assets/img/edit-board.png"/> ],
73+
[
74+
{ content: 'Create or edit the name of this board.', className: 'pos-boardname' },
75+
{ content: 'Board preview.', className:'pos-boardpreview' },
76+
{ content: 'Edit the background appearance of this board.', className:'pos-boardbg' },
77+
{ content: 'Change the size of this board.', className:'pos-boardmeasures' }
78+
]
79+
],
80+
[
81+
[ <img draggable="false" className="imgInfo" src="/dist/assets/img/share-board.png"/> ],
82+
[
83+
{ content: 'Hit Share to get the URL of this board for sharing.', className: 'pos-format' }
84+
]
85+
],
86+
[
87+
[ <img draggable="false" className="imgInfo" src="/dist/assets/img/export-board.png"/> ],
88+
[
89+
{ content: 'Select an export format and hit Export to download the file.', className: 'pos-format' }
90+
]
91+
]
92+
];
93+
94+
return (
95+
<Dialog className="info" infoView={true}
96+
onDismiss={this.props.onDismiss}>
97+
<Carousel ref="carousel" className="infocarousel"
98+
data={this.setCarouselData.bind(this, 'carousel')}>
99+
100+
{objects.map((item) => {
101+
return (
102+
<div>
103+
<TextBoxes items={item[1]} objects={item[0]}/>
104+
</div>
105+
);
106+
})}
107+
</Carousel>
108+
</Dialog>
109+
);
110+
}
111+
});

src/scripts/components/dropdown.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ const DropdownItem = React.createClass({
3838
export default React.createClass({
3939
propTypes: {
4040
show: React.PropTypes.bool.isRequired,
41-
items: React.PropTypes.array
41+
items: React.PropTypes.array,
42+
className: React.PropTypes.string
4243
},
4344

4445
getDefaultProps() {
@@ -53,7 +54,7 @@ export default React.createClass({
5354

5455
render() {
5556
return !this.props.show ? null : (
56-
<ul className="dropdown">
57+
<ul className={`dropdown ${this.props.className}`}>
5758
{this.props.items.map((item, index) => {
5859
return <DropdownItem key={index} {...item} />;
5960
})}

src/scripts/components/navigation.js

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,20 @@ import BroadcastAction from '../actions/broadcast';
77

88
import Dropdown from '../components/dropdown';
99
import UserVoice from '../components/user-voice';
10+
import InfoView from './dialog/view-info';
1011

1112
/**
1213
*
1314
*/
1415
export default React.createClass({
1516
propTypes: {
16-
title: React.PropTypes.string.isRequired
17+
title: React.PropTypes.string.isRequired,
18+
showHelp: React.PropTypes.bool
1719
},
1820

1921
getInitialState() {
20-
return { dropdown: false, feedback: false }
21-
},
22+
return { dropdown: false, feedback: false, infoActive: false }
23+
},
2224

2325
showWorkspace() {
2426
return page.show('/boards');
@@ -27,8 +29,42 @@ export default React.createClass({
2729
toggleDropdown() {
2830
this.setState({ dropdown: !this.state.dropdown });
2931
},
32+
toggleInfoView() {
33+
this.setState({ infoActive: !this.state.infoActive });
34+
},
3035

3136
render: function() {
37+
let infoDialog = null;
38+
let activeClick = null;
39+
let infoIcon = null;
40+
41+
if(!this.state.infoActive) {
42+
infoIcon = 'info';
43+
infoDialog = null;
44+
activeClick = this.toggleDropdown;
45+
} else {
46+
infoIcon = 'times';
47+
infoDialog = <InfoView onDismiss = { this.toggleInfoView} />;
48+
activeClick = () => {};
49+
}
50+
51+
let infoButtonClass =
52+
React.addons.classSet({
53+
infobutton: true,
54+
active: this.state.infoActive
55+
});
56+
let userButtonClass =
57+
React.addons.classSet({
58+
avatar: true,
59+
active: this.state.dropdown
60+
});
61+
62+
let showInfo = !this.props.showHelp ? null : (
63+
<div onClick={this.toggleInfoView} className={infoButtonClass}>
64+
<span className={`fa fa-fw fa-${infoIcon}`}></span>
65+
</div>
66+
);
67+
3268
let items = [
3369
{ icon: 'user', content: 'Profile', disabled: true },
3470
{ icon: 'language', content: 'Localization', disabled: true },
@@ -54,15 +90,18 @@ export default React.createClass({
5490
}
5591
];
5692
return (
57-
<nav className="nav">
93+
<nav id="nav" className="nav">
5894
<img className="logo" src="/dist/assets/img/logo.svg"
5995
onClick={this.showWorkspace} />
6096
<h1 className="title">{this.props.title}</h1>
61-
<div className="avatar" onClick={this.toggleDropdown}>
97+
{showInfo}
98+
<div id="avatar" onClick={activeClick} className={userButtonClass}>
6299
<span className="fa fa-fw fa-user"></span>
63100
</div>
64101
<Dropdown show={this.state.dropdown} items={items} />
102+
{infoDialog}
65103
</nav>
104+
66105
);
67106
}
68107
});

0 commit comments

Comments
 (0)