Share popup UI, change public flag

pull/357/head
Piero Toffanin 2017-12-01 16:10:31 -05:00
rodzic ddb97cff99
commit 2552b82e4f
9 zmienionych plików z 149 dodań i 85 usunięć

Wyświetl plik

@ -159,6 +159,9 @@ footer,
.dropdown-menu .divider{
background-color: theme("border");
}
.popover-title{
border-bottom-color: theme("border");
}
/* Highlight */
.task-list-item:nth-child(odd),

Wyświetl plik

@ -1,6 +1,6 @@
import React from 'react';
import '../css/ShareButton.scss';
import SharePanel from './SharePanel';
import SharePopup from './SharePopup';
import PropTypes from 'prop-types';
import $ from 'jquery';
@ -15,44 +15,29 @@ class ShareButton extends React.Component {
constructor(props){
super(props);
this.state = { showPopup: false };
this.handleClick = this.handleClick.bind(this);
}
handleClick(){
}
componentDidMount(){
const $container = $("<div/>");
$(this.shareButton).popover({
container: 'body',
animation: false,
content: function(){
window.ReactDOM.render(<SharePanel />, $container.get(0));
return $container;
},
html: true,
placement: 'top',
title: "Share"
}).on("shown.bs.popover", () => {
}).on("hidden.bs.popover", () => {
});
}
componentWillUnmount(){
$(this.shareButton).popover('dispose');
this.setState({ showPopup: !this.state.showPopup });
}
render() {
return (
<button
ref={(domNode) => { this.shareButton = domNode; }}
type="button"
className={"shareButton btn btn-sm " + (this.props.task.public ? "btn-primary" : "btn-secondary")}>
<i className="fa fa-share-alt"></i> Share
</button>
<div className="shareButton">
{this.state.showPopup ?
<SharePopup task={this.props.task} />
: ""}
<button
ref={(domNode) => { this.shareButton = domNode; }}
type="button"
onClick={this.handleClick}
className={"shareButton btn btn-sm " + (this.props.task.public ? "btn-primary" : "btn-secondary")}>
<i className="fa fa-share-alt"></i> Share
</button>
</div>
);
}
}

Wyświetl plik

@ -1,45 +0,0 @@
import React from 'react';
import '../css/SharePanel.scss';
import PropTypes from 'prop-types';
class SharePanel extends React.Component{
static propTypes = {
sharingEnabled: PropTypes.bool
};
static defaultProps = {
sharingEnabled: true
};
constructor(props){
super(props);
this.state = {
sharingEnabled: props.sharingEnabled
};
this.handleSharingEnabled = this.handleSharingEnabled.bind(this);
}
handleSharingEnabled(e){
this.setState({ sharingEnabled: e.target.checked });
}
render(){
return (<div className="sharePanel">
<div className="checkbox">
<label>
<input
type="checkbox"
checked={this.state.sharingEnabled}
onChange={this.handleSharingEnabled}
/>
Enable sharing
</label>
</div>
</div>);
}
}
export default SharePanel;

Wyświetl plik

@ -0,0 +1,78 @@
import React from 'react';
import '../css/SharePopup.scss';
import PropTypes from 'prop-types';
import ErrorMessage from './ErrorMessage';
class SharePopup extends React.Component{
static propTypes = {
task: PropTypes.object.isRequired
};
static defaultProps = {
};
constructor(props){
super(props);
this.state = {
task: props.task,
togglingShare: false,
error: ""
};
this.handleEnableSharing = this.handleEnableSharing.bind(this);
}
handleEnableSharing(e){
const { task } = this.state;
this.setState({togglingShare: true});
return $.ajax({
url: `/api/projects/${task.project}/tasks/${task.id}/`,
contentType: 'application/json',
data: JSON.stringify({
public: e.target.checked
}),
dataType: 'json',
type: 'PATCH'
})
.done((task) => {
this.setState({task});
})
.fail(() => this.setState({error: "An error occurred. Check your connection and permissions."}))
.always(() => {
this.setState({togglingShare: false});
});
}
render(){
return (<div className="sharePopup popover top in">
<div className="arrow"></div>
<h3 className="popover-title theme-background-highlight">Share</h3>
<div className="popover-content theme-secondary">
<ErrorMessage bind={[this, 'error']} />
<div className="checkbox">
<label>
{this.state.togglingShare ?
<i className="fa fa-refresh fa-spin fa-fw"></i>
: ""}
<input
className={this.state.togglingShare ? "hide" : ""}
type="checkbox"
checked={this.state.task.public}
onChange={this.handleEnableSharing}
/>
Enable sharing
</label>
</div>
{this.state.task.public ?
<div>A large<br/>bunch<br/>bunch<br/>bunch<br/>bunch<br/>bunch<br/></div>
: ""}
</div>
</div>);
}
}
export default SharePopup;

Wyświetl plik

@ -0,0 +1,11 @@
import React from 'react';
import { shallow } from 'enzyme';
import ShareButton from '../ShareButton';
const taskMock = require('../../tests/utils/MockLoader').load("task.json");
describe('<ShareButton />', () => {
it('renders without exploding', () => {
const wrapper = shallow(<ShareButton task={taskMock} />);
expect(wrapper.exists()).toBe(true);
})
});

Wyświetl plik

@ -0,0 +1,11 @@
import React from 'react';
import { shallow } from 'enzyme';
import SharePopup from '../SharePopup';
const taskMock = require('../../tests/utils/MockLoader').load("task.json");
describe('<SharePopup />', () => {
it('renders without exploding', () => {
const wrapper = shallow(<SharePopup task={taskMock} />);
expect(wrapper.exists()).toBe(true);
})
});

Wyświetl plik

@ -1,9 +1,12 @@
.shareButton{
border-width: 1px;
position: absolute;
z-index: 2000;
bottom: 24px;
right: 76px;
bottom: 12px;
right: 38px;
button{
border-width: 1px;
}
}

Wyświetl plik

@ -1,6 +0,0 @@
.sharePanel{
.checkbox{
margin-top: 0;
}
}

Wyświetl plik

@ -0,0 +1,24 @@
.sharePopup{
position: relative;
top: -56px;
display: block;
&.popover.top > .arrow{
left: auto;
right: 60px;
}
h3.popover-title{
padding-top: 8px;
}
.checkbox{
margin-top: 0;
}
.fa-refresh{
margin-left: -25px;
margin-right: 5px;
}
}