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

Scheduled query browser (Stage 2) #476

Merged
merged 24 commits into from
Jul 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
498420c
Scheduled query browser (Stage 2)
mfix22 Jul 4, 2018
65e53b3
Fix tests
mfix22 Jul 5, 2018
3c4480b
Scheduler -> scheduler
mfix22 Jul 5, 2018
be70c9d
Rename component files
mfix22 Jul 5, 2018
2096fa4
Move getHighlightMode to constants
mfix22 Jul 5, 2018
fd8d17d
Move .scheduleButton to code-editor.css
mfix22 Jul 5, 2018
a9c4d5a
Dispatch scheduled query actions directly w/o redux-actions
mfix22 Jul 5, 2018
863870b
scheduleQuery -> openScheduler, remove unused button
mfix22 Jul 5, 2018
538c041
Address review:
mfix22 Jul 5, 2018
bdaafc7
<Tab disabled={queryPanelDisabled}
mfix22 Jul 5, 2018
26e257c
lowercase Scheduler/ imports
mfix22 Jul 5, 2018
6403926
Move create-modal styles to css file
mfix22 Jul 5, 2018
f7aa830
Remove filename input, generate 8 digit grid name
mfix22 Jul 5, 2018
5eebf5b
Remove 'Create Scheduled Query' button for dialects using editor
mfix22 Jul 5, 2018
706c067
Extract login-modal styles to CSS file
mfix22 Jul 5, 2018
9360312
Add loading and error states for create
mfix22 Jul 5, 2018
e07b8b4
Preview modal loading and error states
mfix22 Jul 5, 2018
cab0265
Error message from server in modal
mfix22 Jul 5, 2018
fea40e4
Prefill filename from generateFilename()
mfix22 Jul 5, 2018
87a8bc2
Pull out intervalType
mfix22 Jul 5, 2018
c61dc54
this.state.filename :+1:
mfix22 Jul 6, 2018
508ca66
Don't call create update delete w/o log in
mfix22 Jul 6, 2018
013c64b
Remove buttons completely when not logged in
mfix22 Jul 6, 2018
f5c8a19
Fix bool proptypes warning
mfix22 Jul 6, 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
76 changes: 74 additions & 2 deletions app/actions/sessions.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export const mergeTabMap = createAction('MERGE_TAB_MAP');
export const setTab = createAction('SET_TAB');
export const setTable = createAction('SET_TABLE');
export const setIndex = createAction('SET_INDEX');
export const setScheduledQueries = createAction('SET_SCHEDULED_QUERIES');
export const mergeConnections = createAction('MERGE_CONNECTIONS');
export const updateConnection = createAction('UPDATE_CREDENTIAL');
export const deleteConnection = createAction('DELETE_CREDENTIAL');
Expand Down Expand Up @@ -145,12 +144,85 @@ export function getScheduledQueries() {
'GET',
'scheduledQueriesRequest'
)).then((json => {
dispatch(setScheduledQueries(json));
dispatch({
type: 'SET_SCHEDULED_QUERIES',
payload: json
});
return json;
}));
};
}

export function createScheduledQuery(connectionId, payload = {}) {
return (dispatch) => {
return dispatch(apiThunk(
'queries',
'POST',
'createScheduledQueryRequest',
payload.filename,
{
requestor: payload.requestor,
uids: payload.uids,
fid: payload.fid,
filename: payload.filename,
refreshInterval: payload.refreshInterval,
query: payload.query,
connectionId
}
)).then((res) => {
dispatch({
type: 'CREATE_SCHEDULED_QUERY',
payload: res
});
return res;
});
};
}

export function updateScheduledQuery(connectionId, payload = {}) {
return (dispatch) => {
const body = {
requestor: payload.requestor,
uids: payload.uids,
fid: payload.fid,
filename: payload.filename,
refreshInterval: payload.refreshInterval,
query: payload.query,
connectionId
};

return dispatch(apiThunk(
'queries',
'POST',
'createScheduledQueryRequest',
payload.filename,
body
)).then((res) => {
dispatch({
type: 'UPDATE_SCHEDULED_QUERY',
payload: body
});
return res;
});
};
}

export function deleteScheduledQuery(fid) {
return (dispatch) => {
return dispatch(apiThunk(
`queries/${fid}`,
'DELETE',
'createScheduledQueryRequest'
)).then((res) => {
dispatch({
type: 'DELETE_SCHEDULED_QUERY',
payload: fid
});
return res;
});
};
}

export function connect(connectionId) {
return apiThunk(
`connections/${connectionId}/connect`,
Expand Down
58 changes: 32 additions & 26 deletions app/components/Settings/Preview/Preview.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Preview extends Component {
getSqlSchema: PropTypes.func,

runSqlQuery: PropTypes.func,
openScheduler: PropTypes.func,
previewTableRequest: PropTypes.object,
queryRequest: PropTypes.object,
elasticsearchMappingsRequest: PropTypes.object,
Expand Down Expand Up @@ -347,6 +348,7 @@ class Preview extends Component {

dialect={dialect}
runQuery={this.runQuery}
openScheduler={this.props.openScheduler}
schemaRequest={schemaRequest}
isLoading={isLoading}
/>
Expand Down Expand Up @@ -454,32 +456,36 @@ class Preview extends Component {
</TabPanel>

<TabPanel>
<div className="export-options-container">
<div style={{margin: '20px 0'}}>
<button
className="btn btn-outline"
onClick={() => this.fetchDatacache(
JSON.stringify(this.state.plotlyJSON),
'plot'
)}
>
Send chart to Chart Studio
</button>
<button
className="btn btn-outline"
onClick={() => this.fetchDatacache(this.getCSVString(), 'grid')}
>
Send CSV to Chart Studio
</button>
{!isOnPrem() &&
<button
className="btn btn-outline"
onClick={() => window.open(
`data:text/csv;base64,${Buffer.from(this.getCSVString()).toString('base64')}`
)}
>
Download CSV
</button>}
<div className="export-options-container" style={{ marginTop: 20 }}>
<div className="container-title">CHART STUDIO</div>
<div className="export-options-group">
<button
className="btn btn-outline"
onClick={() => this.fetchDatacache(
JSON.stringify(this.state.plotlyJSON),
'plot'
)}
>
Upload Chart
</button>
<button
className="btn btn-outline"
onClick={() => this.fetchDatacache(this.getCSVString(), 'grid')}
>
Upload Dataset
</button>
</div>
<div className="container-title">MY COMPUTER</div>
<div className="export-options-group">
{!isOnPrem() &&
<button
className="btn btn-outline"
onClick={() => window.open(
`data:text/csv;base64,${Buffer.from(this.getCSVString()).toString('base64')}`
)}
>
Download CSV
</button>}
</div>
<div style={{width: 650, height: 200, border: '1px solid #dfe8f3',
fontFamily: '\'Ubuntu Mono\', courier, monospace', paddingTop: 10,
Expand Down
7 changes: 7 additions & 0 deletions app/components/Settings/Preview/code-editor.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,10 @@
.react-resizable-handle {
z-index: 9;
}

.scheduleButton {
bottom: 18px;
position: absolute;
right: 136px;
z-index: 10;
}
26 changes: 13 additions & 13 deletions app/components/Settings/Preview/code-editor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import 'react-resizable/css/styles.css';

import './code-editor.css';

import {DIALECTS} from '../../../constants/constants';
import {getHighlightMode} from '../../../constants/constants';

const MIN_CONSTRAINTS_HEIGHT = 74;

Expand All @@ -25,6 +25,7 @@ export default class CodeEditor extends React.Component {

dialect: PropTypes.string,
runQuery: PropTypes.func,
openScheduler: PropTypes.func,
schemaRequest: PropTypes.object,
isLoading: PropTypes.bool
}
Expand Down Expand Up @@ -176,7 +177,8 @@ export default class CodeEditor extends React.Component {
value,
dialect,
runQuery,
isLoading
isLoading,
openScheduler
} = this.props;

const {
Expand All @@ -186,16 +188,7 @@ export default class CodeEditor extends React.Component {
maxConstraints
} = this.state;

const mode = {
[DIALECTS.APACHE_SPARK]: 'text/x-sparksql',
[DIALECTS.MYSQL]: 'text/x-mysql',
[DIALECTS.SQLITE]: 'text/x-sqlite',
[DIALECTS.MARIADB]: 'text/x-mariadb',
[DIALECTS.ORACLE]: 'text/x-plsql',
[DIALECTS.POSTGRES]: 'text/x-pgsql',
[DIALECTS.REDSHIFT]: 'text/x-pgsql',
[DIALECTS.MSSQL]: 'text/x-mssql'
}[dialect] || 'text/x-sql';
const mode = getHighlightMode(dialect);

const options = {
lineNumbers: true,
Expand All @@ -222,10 +215,17 @@ export default class CodeEditor extends React.Component {
onChange={onChange}
editorDidMount={editorDidMount}
/>
<button
className="btn btn-secondary scheduleButton"
onClick={openScheduler}
disabled={isLoading}
>
{isLoading ? 'Loading...' : 'Schedule'}
</button>
<a
className="btn btn-primary runButton"
onClick={runQuery}
disabled={!isLoading}
disabled={isLoading}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch!

>
{isLoading ? 'Loading...' : 'Run'}
</a>
Expand Down
Loading