Skip to content
This repository has been archived by the owner on Jun 4, 2024. It is now read-only.

[WIP] final query scheduling fixes and testing #500

Merged
merged 26 commits into from
Jul 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
bf2d0d1
Disallow editing query name after save
mfix22 Jul 24, 2018
044a866
add log-in warning message to scheduler tab
mfix22 Jul 24, 2018
4771514
enhance login before scheduling a query message
mfix22 Jul 24, 2018
842dd96
fix linting
mfix22 Jul 24, 2018
db76145
add more comprehensive scheduling testing
briandennis Jul 25, 2018
601196c
correct monthly cron interval test comment
briandennis Jul 25, 2018
a13fd98
remove queries won't run warning, add info if logged in as different …
briandennis Jul 25, 2018
96005d4
Minor style fixes
jakedex Jul 25, 2018
d696973
Wrap lines on CreateModal
jakedex Jul 25, 2018
f8e7485
Fix overflow on Schedule and Query pages
jakedex Jul 25, 2018
aa4548a
'Interval' -> 'Schedule' in scheduled table
jakedex Jul 25, 2018
2ba6cee
Add text-overflow for long interval strings
jakedex Jul 25, 2018
fa05078
Misc modal style fixes
jakedex Jul 25, 2018
631d4a6
Fix scheduler double border
jakedex Jul 25, 2018
82c4d56
bump react-chart-editor to 0.21
briandennis Jul 25, 2018
f53ddfc
revert login href change
mfix22 Jul 25, 2018
ddd18e1
Add query name validation
jakedex Jul 25, 2018
0bf0b95
Linting/cleanup
jakedex Jul 25, 2018
75cb763
Copy query to clipboard
jakedex Jul 25, 2018
01572d5
Fix close button position, lint
jakedex Jul 25, 2018
d20fc70
fix preview prop type
briandennis Jul 26, 2018
187aad4
bump react-chart-editor version to 0.21.1
briandennis Jul 26, 2018
2817b2a
add UI signal that query was copied
briandennis Jul 26, 2018
00ce988
trim query name on submit without erroring
briandennis Jul 26, 2018
8c92585
make preview prop optional
briandennis Jul 26, 2018
391bd5a
remove whitespace only error
briandennis Jul 26, 2018
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
1 change: 1 addition & 0 deletions app/components/Settings/Settings.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ class Settings extends Component {
openLogin={this.openLogin}
requestor={username}
dialect={dialect}
preview={preview}
openQueryPage={() => this.updateSelectedPanel(1)}
/>
</TabPanel>
Expand Down
4 changes: 3 additions & 1 deletion app/components/Settings/scheduler/create-modal.css
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
width: 80%;
}

.create-modal .row-body pre {
.create-modal .row-body > pre {
margin-top: 5px;
overflow-y: auto;
max-height: 300px;
}
26 changes: 18 additions & 8 deletions app/components/Settings/scheduler/create-modal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class CreateModal extends Component {
saving: false
};
this.options = {
lineWrapping: true,
lineNumbers: true,
tabSize: 4,
readOnly: false,
Expand Down Expand Up @@ -111,7 +112,7 @@ class CreateModal extends Component {
refreshInterval: DEFAULT_REFRESH_INTERVAL,
filename: generateFilename(),
cronInterval: this.state.interval,
name: this.state.name
name: this.state.name ? this.state.name.trim() : ''
})
.then(() => {
this.setState({successMessage: 'Scheduled query saved successfully!', saving: false});
Expand All @@ -122,7 +123,10 @@ class CreateModal extends Component {
render() {
return (
<Modal open={this.props.open} onClickAway={this.props.onClickAway} className="scheduler create-modal">
<Column className="container" style={{width: '60%', maxHeight: '100vh', minWidth: 640}}>
<Column
className="container"
style={{width: '60%', maxHeight: '100vh', minWidth: 640, paddingBottom: '16px'}}
>
<Row>
<Column className="innerColumn">
<h5 className="header">Create Scheduled Query</h5>
Expand Down Expand Up @@ -152,12 +156,18 @@ class CreateModal extends Component {
<Row style={secondaryRowStyle}>
<div className="row-header">Query name</div>
<div className="row-body">
<input
maxLength="150"
placeholder="Enter query name here..."
value={this.state.name}
onChange={this.handleNameChange}
/>
{this.state.successMessage ? (
<em style={{marginTop: 5, display: 'inherit'}}>
<b>{this.state.name}</b>
</em>
) : (
<input
maxLength="150"
placeholder="Enter query name here..."
value={this.state.name}
onChange={this.handleNameChange}
/>
)}
</div>
</Row>
<Row style={secondaryRowStyle}>
Expand Down
2 changes: 1 addition & 1 deletion app/components/Settings/scheduler/login-modal.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
padding: 16px;
}

.login-modal .submit {
.login-modal .actions button {
width: 50%;
margin: 24px 32px 32px;
}
83 changes: 60 additions & 23 deletions app/components/Settings/scheduler/login-modal.jsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,72 @@
import React from 'react';
import PropTypes from 'prop-types';
import {CopyToClipboard} from 'react-copy-to-clipboard';

import {Row, Column} from '../../layout.jsx';
import Modal from '../../modal.jsx';

import './login-modal.css';

const containerOverrideStyle = {width: '400px'};
const successTextStyle = {color: '#00cc96'};

const PromptLoginModal = props => (
<Modal open={props.open} onClickAway={props.onClickAway} className="scheduler login-modal">
<Column style={containerOverrideStyle} className="container">
<button onClick={props.onClickAway} className="button">
&times;
</button>
<Row className="header">
<p>To create a scheduled query, you'll need to be logged into Plotly.</p>
</Row>
<Row>
<button type="submit" className="submit" onClick={props.onSubmit}>
Log In
</button>
</Row>
</Column>
</Modal>
);

PromptLoginModal.propTypes = {
open: PropTypes.bool.isRequired,
onClickAway: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired
};
class PromptLoginModal extends React.Component {
static propTypes = {
open: PropTypes.bool.isRequired,
preview: PropTypes.object,
onClickAway: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired
};

constructor() {
super();
this.state = {
copyCoolingDown: false
};

this.onCopy = this.onCopy.bind(this);
}

onCopy() {
if (!this.state.copyCoolingDown) {
this.setState({copyCoolingDown: true});
setTimeout(() => this.setState({copyCoolingDown: false}), 2000);
}
}

render() {
return (
<Modal open={this.props.open} onClickAway={this.props.onClickAway} className="scheduler login-modal">
<Column style={containerOverrideStyle} className="container">
<button onClick={this.props.onClickAway} className="button">
&times;
</button>
<Row className="header">
<p>
To create a scheduled query, you'll need to be logged into Plotly.<br />
<br />
Note: logging in will reset your query, click the button below to copy the query to your
clipboard.
</p>
</Row>
<Row className="actions">
<button type="submit" onClick={this.props.onSubmit}>
Log In
</button>
<CopyToClipboard text={this.props.preview ? this.props.preview.code : ''} onCopy={this.onCopy}>
<button className="btn-secondary">
{this.state.copyCoolingDown ? (
<span style={successTextStyle}>Copied!</span>
) : (
'Copy Query'
)}
</button>
</CopyToClipboard>
</Row>
</Column>
</Modal>
);
}
}

export default PromptLoginModal;
88 changes: 68 additions & 20 deletions app/components/Settings/scheduler/preview-modal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ export class PreviewModal extends Component {
onSubmit() {
if (this.state.editing) {
const {connectionId, fid, requestor, uids, refreshInterval} = this.props.query;
const {code: query, cronInterval, name} = this.state;
const {code: query, cronInterval} = this.state;
const name = this.state.name ? this.state.name.trim() : '';

this.setState({loading: true, error: null});
this.props
.onSave({
Expand Down Expand Up @@ -130,14 +132,32 @@ export class PreviewModal extends Component {

renderButtonRow() {
const {loading, editing} = this.state;
const loggedIn = this.props.currentRequestor;
const canEdit = this.props.currentRequestor && this.props.currentRequestor === this.props.query.requestor;
const success = this.state.successMessage;

if (!canEdit) {
return (
<button style={noMargin} onClick={this.props.onLogin}>
Log in to edit query
</button>
<React.Fragment>
{loggedIn ? (
<Column>
<Row>
<p style={{fontSize: 12, marginBottom: '16px', opacity: 0.7, width: '100%'}}>
This query was created by another user. To modify, please log in as that user.
</p>
</Row>
<Row style={{justifyContent: 'flex-start'}}>
<button style={noMargin} onClick={this.props.onLogin}>
{loggedIn ? 'Switch users' : 'Log in to edit query'}
</button>
</Row>
</Column>
) : (
<button style={noMargin} onClick={this.props.onLogin}>
Log in to edit query
</button>
)}
</React.Fragment>
);
}

Expand Down Expand Up @@ -189,36 +209,64 @@ export class PreviewModal extends Component {
const initialModeId = getInitialCronMode(props.query);

content = (
<Column style={{width: '60%', maxHeight: '100vh', minWidth: 640, background: 'white'}}>
<Column
style={{
width: '60%',
maxHeight: '100vh',
minWidth: 640,
background: 'white',
paddingTop: 16,
position: 'relative'
}}
>
<button
onClick={this.close}
style={{
position: 'absolute',
top: '16px',
right: '16px',
padding: '2px 4px',
zIndex: 99
}}
>
&times;
</button>
{editing && (
<Row
style={{
padding: '0 32px',
justifyContent: 'flex-start',
fontSize: 12,
marginTop: 8,
fontWeight: 600,
opacity: 0.4,
letterSpacing: '0.5px'
}}
>
EDITING
</Row>
)}
<Row
className="sql-preview"
style={{
padding: '16px 32px',
padding: '0 32px 16px',
position: 'relative',
justifyContent: 'flex-start'
}}
>
<h5 className="sql-preview ellipsis" style={{...noMargin, letterSpacing: '1px'}}>
{this.state.name ? <b>{this.state.name}</b> : <SQL className="bold">{this.state.code}</SQL>}
</h5>
<button
onClick={this.close}
style={{
position: 'absolute',
top: '16px',
right: '16px',
padding: '2px 4px'
}}
>
&times;
</button>
</Row>
<Column style={{background: '#F5F7FB', padding: '16px 32px'}}>
<Row style={rowStyle}>
<div style={keyStyle}>Query</div>
<div className="sql-preview scheduler" style={{...valueStyle, overflowY: 'auto'}}>
<div
className="sql-preview scheduler"
style={{...valueStyle, overflowY: 'auto', maxHeight: 300}}
>
{editing ? (
<div>
<div style={{width: '99%'}}>
<CodeMirror
options={{
lineNumbers: true,
Expand Down Expand Up @@ -305,7 +353,7 @@ export class PreviewModal extends Component {
justifyContent: 'space-between',
border: 'none',
marginTop: 48,
paddingBottom: 0
paddingBottom: 16
}}
>
{this.renderButtonRow()}
Expand Down
7 changes: 1 addition & 6 deletions app/components/Settings/scheduler/scheduler.css
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,9 @@
}

.scheduler-table .react-grid-Row {
border-top: 1px solid #c8d4e3;
cursor: pointer;
}

.scheduler-table .react-grid-Row:first-child {
border-top: none;
}

.sql pre {
margin: 0 auto;
max-height: 100%;
Expand All @@ -79,5 +74,5 @@
}

.meta-preview button {
min-height: 28px;
min-height: 21px;
}
32 changes: 16 additions & 16 deletions app/components/Settings/scheduler/scheduler.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,19 @@ class IntervalFormatter extends React.Component {
const run = this.props.value;

return (
<Row>
<Column>
<em
style={{
fontSize: 15
}}
>
{run.cronInterval
? cronstrue.toString(run.cronInterval)
: `Runs every ${ms(run.refreshInterval * 1000, {
long: true
})}`}
</em>
</Column>
</Row>
<em
className="ellipsis"
style={{
display: 'block',
fontSize: 15
}}
>
{run.cronInterval
? cronstrue.toString(run.cronInterval)
: `Runs every ${ms(run.refreshInterval * 1000, {
long: true
})}`}
</em>
);
}
}
Expand Down Expand Up @@ -117,6 +115,7 @@ class Scheduler extends Component {
initialCode: PropTypes.string,
requestor: PropTypes.string,
dialect: PropTypes.string,
preview: PropTypes.object,
refreshQueries: PropTypes.func.isRequired,
openLogin: PropTypes.func.isRequired,
createScheduledQuery: PropTypes.func.isRequired,
Expand All @@ -141,7 +140,7 @@ class Scheduler extends Component {
},
{
key: 'run',
name: 'Interval',
name: 'Schedule',
filterable: true,
formatter: IntervalFormatter
}
Expand Down Expand Up @@ -306,6 +305,7 @@ class Scheduler extends Component {
open={!loggedIn && this.state.createModalOpen}
onClickAway={this.closeCreateModal}
onSubmit={this.props.openLogin}
preview={this.props.preview}
/>

{/*
Expand Down
Loading