getredash/redash#2644 Explicit "Add Parameter" Button in Query Editor

This commit is contained in:
Levko Kravets
2018-07-12 18:31:08 +03:00
parent 35bb558f44
commit 2c0ff53894
6 changed files with 114 additions and 63 deletions

View File

@@ -95,10 +95,6 @@ edit-in-place p.editable:hover {
margin-bottom: 10px;
}
.editor__control--right {
text-align: right;
}
.source-control {
}

View File

@@ -1,45 +1,64 @@
<form novalidate ng-submit="$ctrl.close({ $value: $ctrl.parameter })">
<div class="modal-header">
<button type="button" class="close" aria-label="Close" ng-click="$ctrl.close()"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">{{$ctrl.parameter.name}}</h4>
<button type="button" class="close" aria-label="Close" ng-click="$ctrl.dismiss()"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">{{ $ctrl.isNewParameter ? 'Add Parameter' : $ctrl.parameter.name }}</h4>
</div>
<div class="modal-body">
<div class="form">
<div class="form-group">
<label>Title</label>
<input type="text" class="form-control" ng-model="$ctrl.parameter.title">
<div class="form">
<div class="form-group" ng-if="$ctrl.isNewParameter"
ng-class="{'has-error': $ctrl.parameterAlreadyExists($ctrl.parameter.name)}">
<label>Keyword</label>
<input type="text" class="form-control" ng-model="$ctrl.parameter.name">
<div class="help-block" ng-if="!$ctrl.parameterAlreadyExists($ctrl.parameter.name)">
This is what will be added to your query editor<span ng-if="$ctrl.parameter.name != ''">:
\{\{&nbsp;{{ $ctrl.parameter.name }}&nbsp;\}\}</span>
</div>
<div class="form-group">
<label>Type</label>
<select ng-model="$ctrl.parameter.type" class="form-control">
<option value="text">Text</option>
<option value="number">Number</option>
<option value="enum">Dropdown List</option>
<option value="query">Query Based Dropdown List</option>
<option value="date">Date</option>
<option value="datetime-local">Date and Time</option>
<option value="datetime-with-seconds">Date and Time (with seconds)</option>
</select>
</div>
<div class="form-group">
<label>
<input type="checkbox" class="form-inline" ng-model="$ctrl.parameter.global">
Global
</label>
</div>
<div class="form-group" ng-if="$ctrl.parameter.type === 'enum'">
<label>Dropdown List Values (newline delimited)</label>
<textarea class="form-control" rows="3" ng-model="$ctrl.parameter.enumOptions"></textarea>
</div>
<div class="form-group" ng-if="$ctrl.parameter.type === 'query'">
<label>Query to load dropdown values from:</label>
<ui-select ng-model="$ctrl.parameter.queryId" reset-search-input="false">
<ui-select-match placeholder="Search a query by name">{{$select.selected.name}}</ui-select-match>
<ui-select-choices repeat="q.id as q in $ctrl.queries"
refresh="$ctrl.searchQueries($select.search)"
refresh-delay="0">
<div class="form-group" ng-bind-html="$ctrl.trustAsHtml(q.name | highlight: $select.search)"></div>
</ui-select-choices>
</ui-select>
<div class="help-block" ng-if="$ctrl.parameterAlreadyExists($ctrl.parameter.name)">
Parameter with this name already exists.
</div>
</div>
<div class="form-group">
<label>Title</label>
<input type="text" class="form-control" ng-model="$ctrl.parameter.title">
</div>
<div class="form-group">
<label>Type</label>
<select ng-model="$ctrl.parameter.type" class="form-control">
<option value="text">Text</option>
<option value="number">Number</option>
<option value="enum">Dropdown List</option>
<option value="query">Query Based Dropdown List</option>
<option value="date">Date</option>
<option value="datetime-local">Date and Time</option>
<option value="datetime-with-seconds">Date and Time (with seconds)</option>
</select>
</div>
<div class="form-group">
<label>
<input type="checkbox" class="form-inline" ng-model="$ctrl.parameter.global">
Global
</label>
</div>
<div class="form-group" ng-if="$ctrl.parameter.type === 'enum'">
<label>Dropdown List Values (newline delimited)</label>
<textarea class="form-control" rows="3" ng-model="$ctrl.parameter.enumOptions"></textarea>
</div>
<div class="form-group" ng-if="$ctrl.parameter.type === 'query'">
<label>Query to load dropdown values from:</label>
<ui-select ng-model="$ctrl.parameter.queryId" reset-search-input="false">
<ui-select-match placeholder="Search a query by name">{{$select.selected.name}}</ui-select-match>
<ui-select-choices repeat="q.id as q in $ctrl.queries"
refresh="$ctrl.searchQueries($select.search)"
refresh-delay="0">
<div class="form-group" ng-bind-html="$ctrl.trustAsHtml(q.name | highlight: $select.search)"></div>
</ui-select-choices>
</ui-select>
</div>
</div>
</div>
<div class="modal-footer p-t-0" ng-if="$ctrl.isNewParameter">
<button type="button" class="btn btn-default pull-left" ng-click="$ctrl.dismiss()">Close</button>
<button type="submit" class="btn btn-primary pull-right"
ng-disabled="($ctrl.parameter.name == '') || $ctrl.parameterAlreadyExists($ctrl.parameter.name)">+ Add Parameter</button>
</div>
</form>

View File

@@ -1,4 +1,4 @@
import { find } from 'lodash';
import { find, includes } from 'lodash';
import template from './parameters.html';
import queryBasedParameterTemplate from './query-based-parameter.html';
import parameterSettingsTemplate from './parameter-settings.html';
@@ -15,6 +15,9 @@ const ParameterSettingsComponent = {
this.trustAsHtml = html => $sce.trustAsHtml(html);
this.parameter = this.resolve.parameter;
this.isNewParameter = this.parameter.name === '';
this.parameterAlreadyExists = name => includes(this.resolve.existingParameters, name);
if (this.parameter.queryId) {
Query.get({ id: this.parameter.queryId }, (query) => {

View File

@@ -152,27 +152,28 @@
</p>
<div class="editor__control">
<div class="row form-inline">
<div class="col-xs-5 text-left">
<select class="form-control datasource-small" ng-disabled="!isQueryOwner || !sourceMode" ng-model="query.data_source_id"
ng-change="updateDataSource()" ng-options="ds.id as ds.name for ds in dataSources"></select>
</div>
<div class="form-inline d-flex">
<button type="button" class="btn btn-default m-r-5" ng-click="addNewParameter()">
<span ng-non-bindable>{{&nbsp;}}</span>
</button>
<div class="col-xs-7">
<div class="editor__control--right">
<button class="btn btn-default" ng-show="canEdit" ng-click="saveQuery()" title="Save">
<span class="fa fa-floppy-o"></span>
<span class="hidden-xs">Save</span>
<span ng-show="isDirty">&#42;</span>
</button>
<select class="form-control datasource-small flex-fill w-100"
ng-disabled="!isQueryOwner || !sourceMode" ng-model="query.data_source_id"
ng-change="updateDataSource()"
ng-options="ds.id as ds.name for ds in dataSources"></select>
<button type="button" class="btn btn-primary" ng-disabled="queryExecuting || !canExecuteQuery()" ng-click="executeQuery()">
<span class="zmdi zmdi-play"></span>
<span class="hidden-xs">Execute</span>
</button>
</div>
</div>
<button class="btn btn-default m-l-5" ng-show="canEdit" ng-click="saveQuery()" title="Save">
<span class="fa fa-floppy-o"></span>
<span class="hidden-xs">Save</span>
<span
ng-show="isDirty">&#42;</span>
</button>
<button type="button" class="btn btn-primary m-l-5"
ng-disabled="queryExecuting || !canExecuteQuery()" ng-click="executeQuery()">
<span class="zmdi zmdi-play"></span>
<span class="hidden-xs">Execute</span>
</button>
</div>
</div>
</div>
@@ -318,4 +319,4 @@
</div>
</div>
</main>
</div>
</div>

View File

@@ -1,8 +1,10 @@
import { map } from 'lodash';
import template from './query.html';
function QuerySourceCtrl(
Events, toastr, $controller, $scope, $location, $http, $q,
Events, toastr, $controller, $scope, $location, $http, $q, $uibModal,
AlertDialog, currentUser, Query, Visualization, KeyboardShortcuts,
$rootScope,
) {
// extends QueryViewCtrl
$controller('QueryViewCtrl', { $scope });
@@ -30,6 +32,9 @@ function QuerySourceCtrl(
$scope.saveQuery();
}
},
'shift+alt+p': () => {
$scope.addNewParameter();
},
};
KeyboardShortcuts.bind(shortcuts);
@@ -65,6 +70,25 @@ function QuerySourceCtrl(
.catch(error => toastr.error(error));
};
$scope.addNewParameter = () => {
$uibModal.open({
component: 'parameterSettings',
resolve: {
parameter: {
title: '',
name: '',
type: 'text',
value: null,
global: false,
},
existingParameters: () => map($scope.query.getParameters().get(), p => p.name),
},
}).result.then((param) => {
$rootScope.$broadcast('query-editor.paste', '{{ ' + param.name + ' }}');
$scope.query.getParameters().add(param);
});
};
$scope.$watch('query.query', (newQueryText) => {
$scope.isDirty = (newQueryText !== queryText);
});

View File

@@ -139,6 +139,14 @@ class Parameters {
return this.query.options.parameters;
}
add(parameterDef) {
if (isObject(parameterDef)) {
this.query.options.parameters = this.query.options.parameters
.filter(p => p.name !== parameterDef.name);
this.query.options.parameters.push(new Parameter(parameterDef));
}
}
getMissing() {
return map(
filter(this.get(), p => p.value === null || p.value === ''),