Skip to content

Commit

Permalink
Migrated AddTextboxDialog to AntD (#3524)
Browse files Browse the repository at this point in the history
  • Loading branch information
ranbena authored Mar 4, 2019
1 parent dd0fab7 commit 34da15f
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 137 deletions.
195 changes: 72 additions & 123 deletions client/app/components/dashboards/AddTextboxDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,154 +2,103 @@ import { markdown } from 'markdown';
import { debounce } from 'lodash';
import React from 'react';
import PropTypes from 'prop-types';
import { react2angular } from 'react2angular';
import Modal from 'antd/lib/modal';
import Input from 'antd/lib/input';
import Tooltip from 'antd/lib/tooltip';
import Divider from 'antd/lib/divider';
import { wrap as wrapDialog, DialogPropType } from '@/components/DialogWrapper';
import { toastr } from '@/services/ng';
import { Widget } from '@/services/widget';

import './AddTextboxDialog.less';

class AddTextboxDialog extends React.Component {
static propTypes = {
dashboard: PropTypes.object, // eslint-disable-line react/forbid-prop-types
close: PropTypes.func,
dismiss: PropTypes.func,
};

static defaultProps = {
dashboard: null,
close: () => {},
dismiss: () => {},
dashboard: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
dialog: DialogPropType.isRequired,
onConfirm: PropTypes.func.isRequired,
};

constructor(props) {
super(props);
this.state = {
saveInProgress: false,
text: '',
preview: '',
};
state = {
saveInProgress: false,
text: '',
preview: '',
}

const updatePreview = debounce(() => {
const text = this.state.text;
this.setState({
preview: markdown.toHTML(text),
});
}, 100);
updatePreview = debounce(() => {
const text = this.state.text;
this.setState({
preview: markdown.toHTML(text),
});
}, 100);

this.onTextChanged = (event) => {
this.setState({ text: event.target.value });
updatePreview();
};
}
onTextChanged = (event) => {
this.setState({ text: event.target.value });
this.updatePreview();
};

saveWidget() {
const dashboard = this.props.dashboard;

this.setState({ saveInProgress: true });

const widget = new Widget({
visualization_id: null,
dashboard_id: dashboard.id,
options: {
isHidden: false,
position: {},
},
visualization: null,
text: this.state.text,
});

const position = dashboard.calculateNewWidgetPosition(widget);
widget.options.position.col = position.col;
widget.options.position.row = position.row;

widget
.save()
this.props.onConfirm(this.state.text)
.then(() => {
dashboard.widgets.push(widget);
this.props.close();
this.props.dialog.close();
})
.catch(() => {
toastr.error('Widget can not be added');
toastr.error('Widget could not be added');
})
.finally(() => {
this.setState({ saveInProgress: false });
});
}

render() {
return (
<div>
<div className="modal-header">
<button
type="button"
className="close"
disabled={this.state.saveInProgress}
aria-hidden="true"
onClick={this.props.dismiss}
>
&times;
</button>
<h4 className="modal-title">Add Textbox</h4>
</div>
<div className="modal-body">
<div className="form-group m-b-0">
<textarea
className="form-control resize-vertical"
style={{ minMeight: '100px' }}
rows="5"
value={this.state.text}
onChange={this.onTextChanged}
/>
</div>
<div
ng-show="$ctrl.text"
className="m-t-15"
>
<strong>Preview:</strong>
<p
dangerouslySetInnerHTML={{ __html: this.state.preview }} // eslint-disable-line react/no-danger
className="word-wrap-break"
/>
</div>
</div>
const { dialog } = this.props;

<div className="modal-footer">
<button
type="button"
className="btn btn-default"
disabled={this.state.saveInProgress}
onClick={this.props.dismiss}
>
Close
</button>
<button
type="button"
className="btn btn-primary"
disabled={this.state.saveInProgress}
onClick={() => this.saveWidget()}
>
Add to Dashboard
</button>
return (
<Modal
{...dialog.props}
title="Add Textbox"
onOk={() => this.saveWidget()}
okButtonProps={{
loading: this.state.saveInProgress,
disabled: !this.state.text,
}}
okText="Add to Dashboard"
width={500}
>
<div className="add-textbox">
<Input.TextArea
className="resize-vertical"
rows="5"
value={this.state.text}
onChange={this.onTextChanged}
autoFocus
placeholder="This is where you write some text"
/>
<small>
Supports basic{' '}
<a
target="_blank"
rel="noopener noreferrer"
href="https://www.markdownguide.org/cheat-sheet/#basic-syntax"
>
<Tooltip title="Markdown guide opens in new window">Markdown</Tooltip>
</a>.
</small>
{this.state.text && (
<React.Fragment>
<Divider dashed />
<strong className="preview-title">Preview:</strong>
<p
dangerouslySetInnerHTML={{ __html: this.state.preview }} // eslint-disable-line react/no-danger
className="preview"
/>
</React.Fragment>
)}
</div>
</div>
</Modal>
);
}
}

export default function init(ngModule) {
ngModule.component('addTextboxDialog', {
template: `
<add-textbox-dialog-impl
dashboard="$ctrl.resolve.dashboard"
close="$ctrl.close"
dismiss="$ctrl.dismiss"
></add-textbox-dialog-impl>
`,
bindings: {
resolve: '<',
close: '&',
dismiss: '&',
},
});
ngModule.component('addTextboxDialogImpl', react2angular(AddTextboxDialog));
}

init.init = true;
export default wrapDialog(AddTextboxDialog);
18 changes: 18 additions & 0 deletions client/app/components/dashboards/AddTextboxDialog.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.add-textbox {
small {
display: block;
margin-top: 4px;
}

.preview {
padding: 9px 9px 1px;
background-color: #f7f7f7;
margin-top: 8px;
word-wrap: break-word
}

.preview-title {
display: block;
margin-top: -5px;
}
}
2 changes: 1 addition & 1 deletion client/app/components/dashboards/AddWidgetDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class AddWidgetDialog extends React.Component {
this.props.dialog.close();
})
.catch(() => {
toastr.error('Widget can not be added');
toastr.error('Widget could not be added');
})
.finally(() => {
this.setState({ saveInProgress: false });
Expand Down
45 changes: 32 additions & 13 deletions client/app/pages/dashboards/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { durationHumanize } from '@/filters';
import template from './dashboard.html';
import ShareDashboardDialog from './ShareDashboardDialog';
import AddWidgetDialog from '@/components/dashboards/AddWidgetDialog';
import AddTextboxDialog from '@/components/dashboards/AddTextboxDialog';

import './dashboard.less';

function isWidgetPositionChanged(oldPosition, newPosition) {
Expand Down Expand Up @@ -325,25 +327,40 @@ function DashboardCtrl(
};

this.showAddTextboxDialog = () => {
$uibModal
.open({
component: 'addTextboxDialog',
resolve: {
dashboard: () => this.dashboard,
},
})
.result.then(this.onWidgetAdded);
AddTextboxDialog.showModal({
dashboard: this.dashboard,
onConfirm: this.addTextbox,
});
};

this.addTextbox = (text) => {
const widget = new Widget({
dashboard_id: this.dashboard.id,
options: {
isHidden: false,
position: {},
},
text,
visualization: null,
visualization_id: null,
});

const position = this.dashboard.calculateNewWidgetPosition(widget);
widget.options.position.col = position.col;
widget.options.position.row = position.row;

return widget.save()
.then(() => {
this.dashboard.widgets.push(widget);
this.onWidgetAdded();
});
};

this.showAddWidgetDialog = () => {
AddWidgetDialog.showModal({
dashboard: this.dashboard,
onConfirm: this.addWidget,
})
.result.then(() => {
this.onWidgetAdded();
$scope.$applyAsync();
});
});
};

this.addWidget = (selectedVis, parameterMappings) => {
Expand Down Expand Up @@ -371,6 +388,7 @@ function DashboardCtrl(
return Promise.all(widgetsToSave.map(w => w.save()))
.then(() => {
this.dashboard.widgets.push(widget);
this.onWidgetAdded();
});
};

Expand All @@ -381,6 +399,7 @@ function DashboardCtrl(
if (_.isObject(widget)) {
return widget.save();
}
$scope.$applyAsync();
};

this.removeWidget = (widgetId) => {
Expand Down

0 comments on commit 34da15f

Please sign in to comment.