Skip to content

Commit

Permalink
Parameter feedback - #5 Unsaved indication
Browse files Browse the repository at this point in the history
  • Loading branch information
ranbena committed Oct 31, 2019
1 parent 557c9ba commit f95570d
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 9 deletions.
23 changes: 20 additions & 3 deletions client/app/components/Parameters.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { size, filter, forEach, extend, get } from 'lodash';
import { size, filter, forEach, extend, get, includes } from 'lodash';
import { react2angular } from 'react2angular';
import { SortableContainer, SortableElement, DragHandle } from '@/components/sortable';
import { $location } from '@/services/ng';
Expand Down Expand Up @@ -34,6 +34,7 @@ export class Parameters extends React.Component {
queryResultErrorData: PropTypes.shape({
parameters: PropTypes.objectOf(PropTypes.string),
}),
unsavedParameters: PropTypes.arrayOf(PropTypes.string),
};

static defaultProps = {
Expand All @@ -44,6 +45,7 @@ export class Parameters extends React.Component {
onPendingValuesChange: () => {},
onParametersEdit: () => {},
queryResultErrorData: {},
unsavedParameters: null,
};

constructor(props) {
Expand Down Expand Up @@ -140,7 +142,22 @@ export class Parameters extends React.Component {
const { queryResultErrorData } = this.props;
const error = get(queryResultErrorData, ['parameters', param.name], false);
if (error) {
return [error, 'error'];
const feedback = <Tooltip title={error}>{error}</Tooltip>;
return [feedback, 'error'];
}

// unsaved
const { unsavedParameters } = this.props;
if (includes(unsavedParameters, param.name)) {
const feedback = (
<>
Unsaved{' '}
<Tooltip title='Click the "Save" button to preserve this parameter.'>
<i className="fa fa-question-circle" />
</Tooltip>
</>
);
return [feedback, 'warning'];
}

return [];
Expand Down Expand Up @@ -172,7 +189,7 @@ export class Parameters extends React.Component {
</div>
<Form.Item
validateStatus={touched ? '' : status}
help={feedback ? <Tooltip title={feedback}>{feedback}</Tooltip> : null}
help={feedback || null}
>
<ParameterValueInput
type={param.type}
Expand Down
2 changes: 1 addition & 1 deletion client/app/pages/queries/query.html
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ <h3>
<div class="d-flex flex-column p-b-15 p-absolute static-position__mobile" style="left: 0; top: 0; right: 0; bottom: 0;">
<div class="p-t-15 p-b-5" ng-if="query.hasParameters()">
<parameters parameters="query.getParametersDefs()" query-result-error-data="queryResult.getErrorData()" editable="sourceMode && canEdit" disable-url-update="query.isNew()"
on-values-change="executeQuery" on-pending-values-change="applyParametersChanges" on-parameters-edit="onParametersUpdated"></parameters>
on-values-change="executeQuery" on-pending-values-change="applyParametersChanges" on-parameters-edit="onParametersUpdated" unsaved-parameters="getUnsavedParameters()"></parameters>
</div>
<!-- Query Execution Status -->

Expand Down
17 changes: 16 additions & 1 deletion client/app/pages/queries/source-view.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { map, debounce } from 'lodash';
import { map, debounce, isEmpty, isEqual } from 'lodash';
import template from './query.html';
import EditParameterSettingsDialog from '@/components/EditParameterSettingsDialog';

Expand Down Expand Up @@ -109,6 +109,21 @@ function QuerySourceCtrl(
$scope.$watch('query.query', (newQueryText) => {
$scope.isDirty = newQueryText !== queryText;
});

$scope.unsavedParameters = null;
$scope.getUnsavedParameters = () => {
if (!$scope.isDirty || !queryText) {
return null;
}
const unsavedParameters = $scope.query.$parameters.getUnsavedParameters(queryText);
if (isEmpty(unsavedParameters)) {
return null;
}
if (!isEqual(unsavedParameters, $scope.unsavedParameters)) {
$scope.unsavedParameters = unsavedParameters;
}
return $scope.unsavedParameters;
};
}

export default function init(ngModule) {
Expand Down
14 changes: 10 additions & 4 deletions client/app/services/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import debug from 'debug';
import Mustache from 'mustache';
import {
zipObject, isEmpty, map, includes, union,
uniq, has, identity, extend, each, some,
uniq, has, identity, extend, each, some, reject,
} from 'lodash';

import { Parameter } from './parameters';
Expand Down Expand Up @@ -35,13 +35,14 @@ class Parameters {
this.initFromQueryString(queryString);
}

parseQuery() {
parseQuery(queryText = null) {
const fallback = () => map(this.query.options.parameters, i => i.name);
queryText = queryText || this.query.query;

let parameters = [];
if (this.query.query !== undefined) {
if (queryText !== undefined) {
try {
const parts = Mustache.parse(this.query.query);
const parts = Mustache.parse(queryText);
parameters = uniq(collectParams(parts));
} catch (e) {
logger('Failed parsing parameters: ', e);
Expand Down Expand Up @@ -124,6 +125,11 @@ class Parameters {
each(this.get(), p => p.applyPendingValue());
}

getUnsavedParameters(queryText) {
const savedParameters = this.parseQuery(queryText);
return reject(this.get(), p => includes(savedParameters, p.name)).map(p => p.name);
}

toUrlParams() {
if (this.get().length === 0) {
return '';
Expand Down

0 comments on commit f95570d

Please sign in to comment.