Skip to content

Commit

Permalink
Merge pull request #6 from getredash/master
Browse files Browse the repository at this point in the history
pull from upstream 7.29.18
  • Loading branch information
alison985 authored Jul 30, 2018
2 parents c51edd3 + 016166c commit ea91d91
Show file tree
Hide file tree
Showing 23 changed files with 1,281 additions and 686 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Change Log

## v5.0.0-Beta - UNRELEASED

## v4.0.1 - 2018-05-02

### Added
Expand Down
4 changes: 4 additions & 0 deletions client/.babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
"transform-object-assign",
["babel-plugin-transform-builtin-extend", {
"globals": ["Error"]
}],
["import", {
"libraryName": "antd",
"style": true
}]
]
}
37 changes: 37 additions & 0 deletions client/app/components/DateInput.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import moment from 'moment';
import React from 'react';
import PropTypes from 'prop-types';
import { react2angular } from 'react2angular';
import { DatePicker } from 'antd';

function DateInput({
value,
onSelect,
clientConfig,
}) {
const format = clientConfig.dateFormat || 'YYYY-MM-DD';
const defaultValue = moment(value, format);
return (
<DatePicker
{...(defaultValue.isValid() ? { defaultValue } : {})}
format={format}
placeholder="Select Date"
onChange={onSelect}
/>
);
}

DateInput.propTypes = {
value: PropTypes.instanceOf(Date),
onSelect: PropTypes.func,
};

DateInput.defaultProps = {
value: Date.now(),
onSelect: () => {},
};

export default function init(ngModule) {
ngModule.component('dateInput', react2angular(DateInput, null, ['clientConfig']));
}

42 changes: 42 additions & 0 deletions client/app/components/DateTimeInput.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import moment from 'moment';
import React from 'react';
import PropTypes from 'prop-types';
import { react2angular } from 'react2angular';
import { DatePicker } from 'antd';

function DateTimeInput({
value,
withSeconds,
onSelect,
clientConfig,
}) {
const format = (clientConfig.dateFormat || 'YYYY-MM-DD') +
(withSeconds ? ' HH:mm:ss' : ' HH:mm');
const defaultValue = moment(value, format);
return (
<DatePicker
showTime
{...(defaultValue.isValid() ? { defaultValue } : {})}
format={format}
placeholder="Select Date and Time"
onChange={onSelect}
/>
);
}

DateTimeInput.propTypes = {
value: PropTypes.instanceOf(Date),
withSeconds: PropTypes.bool,
onSelect: PropTypes.func,
};

DateTimeInput.defaultProps = {
value: Date.now(),
withSeconds: false,
onSelect: () => {},
};

export default function init(ngModule) {
ngModule.component('dateTimeInput', react2angular(DateTimeInput, null, ['clientConfig']));
}

9 changes: 6 additions & 3 deletions client/app/components/parameters.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@
<i class="zmdi zmdi-settings"></i>
</button>
<span ng-switch="param.type">
<input ng-switch-when="datetime-with-seconds" type="datetime-local" step="1" class="form-control" ng-model="param.ngModel">
<input ng-switch-when="datetime-local" type="datetime-local" class="form-control" ng-model="param.ngModel">
<input ng-switch-when="date" type="date" class="form-control" ng-model="param.ngModel">
<date-time-input ng-switch-when="datetime-with-seconds" value="param.ngModel" with-seconds="true"
on-select="param.updateValue"></date-time-input>
<date-time-input ng-switch-when="datetime-local" value="param.ngModel"
on-select="param.updateValue"></date-time-input>
<date-input ng-switch-when="date" value="param.ngModel"
on-select="param.updateValue"></date-input>
<span ng-switch-when="enum">
<select ng-model="param.value" class="form-control">
<option ng-repeat="option in extractEnumOptions(param.enumOptions)" value="{{option}}">{{option}}</option>
Expand Down
1 change: 1 addition & 0 deletions client/app/components/queries/query-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'brace/mode/python';
import 'brace/mode/sql';
import 'brace/mode/json';
import 'brace/ext/language_tools';
import 'brace/ext/searchbox';
import { map } from 'lodash';

// By default Ace will try to load snippet files for the different modes and fail.
Expand Down
22 changes: 15 additions & 7 deletions client/app/pages/admin/status/status.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@

<div class="bg-white tiled">
<ul class="tab-nav">
<li class="active"><a href="admin/status">System Status</a></li>
<li><a href="admin/queries/tasks">Queries Queue</a></li>
<li><a href="admin/queries/outdated">Outdated Queries</a></li>
<li class="active">
<a href="admin/status">System Status</a>
</li>
<li>
<a href="admin/queries/tasks">Queries Queue</a>
</li>
<li>
<a href="admin/queries/outdated">Outdated Queries</a>
</li>
</ul>


Expand Down Expand Up @@ -39,12 +45,14 @@
<li class="list-group-item active">Queues</li>
<li class="list-group-item" ng-repeat="(name, value) in manager.queues">
<span class="badge">{{value.size}}</span>
{{name}} <span uib-popover="{{value.data_sources}}" popover-trigger="'mouseenter'"><i class="fa fa-question-circle"></i></span>
{{name}}
<span uib-popover="{{value.data_sources}}" popover-trigger="'mouseenter'">
<i class="fa fa-question-circle"></i>
</span>
</li>
</ul>
</div>
<BR>
<div>
<div class="row p-15">
<ul class="list-group col-lg-4">
<li class="list-group-item active">Redash Database</li>
<li class="list-group-item" ng-repeat="(name, size) in database_metrics.metrics">
Expand All @@ -54,4 +62,4 @@
</ul>
</div>
</div>
</div>
</div>
10 changes: 7 additions & 3 deletions client/app/pages/queries/query.html
Original file line number Diff line number Diff line change
Expand Up @@ -216,14 +216,18 @@ <h3>
<button type="button" class="btn btn-warning btn-xs pull-right" ng-disabled="cancelling" ng-click="cancelExecution()">Cancel
</button>
</div>
<div class="alert alert-info m-t-15" ng-show="queryResult.getStatus() == 'loading-result'">
Loading results&hellip;
<rd-timer timestamp="queryResult.getUpdatedAt()"></rd-timer>
</div>
<div class="alert alert-info m-t-15" ng-show="queryResult.getStatus() == 'waiting'">
Query in queue&hellip;
<rd-timer timestamp="queryResult.getUpdatedAt()"></rd-timer>
<button type="button" class="btn btn-warning btn-xs pull-right" ng-disabled="cancelling" ng-click="cancelExecution()">Cancel
</button>
</div>
<div class="alert alert-danger m-t-15" ng-show="queryResult.getError()">Error running query:
<strong>{{queryResult.getError()}}</strong>
<div class="alert alert-danger m-t-15" ng-show="queryResult.getError()">
Error running query: <strong>{{queryResult.getError()}}</strong>
</div>
</div>
<!-- End of Query Execution Status -->
Expand Down Expand Up @@ -318,4 +322,4 @@ <h3>
</div>
</div>
</main>
</div>
</div>
23 changes: 21 additions & 2 deletions client/app/services/query-result.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ function QueryResultService($resource, $timeout, $q) {

this.updatedAt = moment();

// exteded status flags
this.isLoadingResult = false;

if (props) {
this.update(props);
}
Expand Down Expand Up @@ -148,6 +151,9 @@ function QueryResultService($resource, $timeout, $q) {
}

getStatus() {
if (this.isLoadingResult) {
return 'loading-result';
}
return this.status || statuses[this.job.status];
}

Expand Down Expand Up @@ -335,7 +341,6 @@ function QueryResultService($resource, $timeout, $q) {
return this.columnNames;
}


getColumnCleanNames() {
return this.getColumnNames().map(col => getColumnCleanName(col));
}
Expand Down Expand Up @@ -414,18 +419,32 @@ function QueryResultService($resource, $timeout, $q) {
static getById(id) {
const queryResult = new QueryResult();

queryResult.isLoadingResult = true;
QueryResultResource.get({ id }, (response) => {
// Success handler
queryResult.isLoadingResult = false;
queryResult.update(response);
}, (response) => {
// Error handler
queryResult.isLoadingResult = false;
queryResult.update({
job: {
error: response.data.message,
status: 4,
},
});
});

return queryResult;
}

loadResult(tryCount) {
this.isLoadingResult = true;
QueryResultResource.get(
{ id: this.job.query_result_id },
(response) => {
this.update(response);
this.isLoadingResult = false;
},
(error) => {
if (tryCount === undefined) {
Expand All @@ -440,6 +459,7 @@ function QueryResultService($resource, $timeout, $q) {
status: 4,
},
});
this.isLoadingResult = false;
} else {
$timeout(() => {
this.loadResult(tryCount + 1);
Expand Down Expand Up @@ -508,7 +528,6 @@ function QueryResultService($resource, $timeout, $q) {
}
}


return QueryResult;
}

Expand Down
59 changes: 19 additions & 40 deletions client/app/services/query.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
import moment from 'moment';
import debug from 'debug';
import Mustache from 'mustache';
import {
each,
zipObject,
isEmpty,
map,
filter,
includes,
union,
uniq,
has,
} from 'lodash';
import { each, zipObject, isEmpty, map, filter, includes, union, uniq, has } from 'lodash';

const logger = debug('redash:services:query');

Expand All @@ -38,14 +28,16 @@ class Parameter {
this.global = parameter.global;
this.enumOptions = parameter.enumOptions;
this.queryId = parameter.queryId;

// method to update parameter value from date/time picker component
// (react does not support two-way binding with `ngModel`)
this.updateValue = (value) => {
this.ngModel = value;
};
}

get ngModel() {
if (
this.type === 'date' ||
this.type === 'datetime-local' ||
this.type === 'datetime-with-seconds'
) {
if (this.type === 'date' || this.type === 'datetime-local' || this.type === 'datetime-with-seconds') {
this.$$value = this.$$value || moment(this.value).toDate();
return this.$$value;
} else if (this.type === 'number') {
Expand Down Expand Up @@ -120,9 +112,7 @@ class Parameters {
});

const parameterExists = p => includes(parameterNames, p.name);
this.query.options.parameters = this.query.options.parameters
.filter(parameterExists)
.map(p => new Parameter(p));
this.query.options.parameters = this.query.options.parameters.filter(parameterExists).map(p => new Parameter(p));
}

initFromQueryString(queryString) {
Expand All @@ -140,10 +130,7 @@ class Parameters {
}

getMissing() {
return map(
filter(this.get(), p => p.value === null || p.value === ''),
i => i.title,
);
return map(filter(this.get(), p => p.value === null || p.value === ''), i => i.title);
}

isRequired() {
Expand All @@ -156,14 +143,7 @@ class Parameters {
}
}

function QueryResource(
$resource,
$http,
$q,
$location,
currentUser,
QueryResult,
) {
function QueryResource($resource, $http, $q, $location, currentUser, QueryResult) {
class QueryResultError {
constructor(errorMessage) {
this.errorMessage = errorMessage;
Expand Down Expand Up @@ -239,6 +219,12 @@ function QueryResource(
url: 'api/queries/:id/favorite',
transformRequest: [() => ''], // body not needed
},
// This can be removed once #2686 is merged:
search: {
method: 'get',
isArray: true,
url: 'api/queries/search',
},
},
);

Expand All @@ -261,9 +247,7 @@ function QueryResource(
return $q.reject(String(err));
}
} else if (syntax === 'sql') {
return $http
.post('api/queries/format', { query })
.then(response => response.data.query);
return $http.post('api/queries/format', { query }).then(response => response.data.query);
} else {
return $q.reject('Query formatting is not supported for your data source syntax.');
}
Expand Down Expand Up @@ -343,12 +327,7 @@ function QueryResource(
this.queryResult = QueryResult.getById(this.latest_query_data_id);
}
} else if (this.data_source_id) {
this.queryResult = QueryResult.get(
this.data_source_id,
queryText,
maxAge,
this.id,
);
this.queryResult = QueryResult.get(this.data_source_id, queryText, maxAge, this.id);
} else {
return new QueryResultError('Please select data source to run this query.');
}
Expand Down
Loading

0 comments on commit ea91d91

Please sign in to comment.