mirror of
https://github.com/getredash/redash.git
synced 2025-12-19 17:37:19 -05:00
* Allow multiple values for enum parameter * Allow multi-select for Query dropdown parameters * CR + make sure list values are allowed * Add prefix, suffix and separator * Rename multipleValues and cast options as strings * Replicate serialization logic on frontend * Add Quote Option Select * Make sure it's enum or query before join * Add a couple of tests * Add help to quote option * Add min-width and normalize empty array * Improve behavior when changing parameter settings - Set parameter value again to pass through checks - Add setValue check for multi values * Validate enum values on setValue + CodeClimate * Ran wording suggestions * Updates after Apply Changes * Fix failing Cypress tests * Make sure enumOptions exists before split * Improve propTypes for QueyBasedParameterInput Co-Authored-By: Ran Byron <ranbena@gmail.com> * CR * Cypress: Test for multi-select Enum * Fix multi-selection Cypress spec * Update Refresh Schedule
99 lines
2.7 KiB
JavaScript
99 lines
2.7 KiB
JavaScript
import { extend, filter, forEach, size } from 'lodash';
|
|
import template from './parameters.html';
|
|
import EditParameterSettingsDialog from './EditParameterSettingsDialog';
|
|
|
|
function ParametersDirective($location, KeyboardShortcuts) {
|
|
return {
|
|
restrict: 'E',
|
|
transclude: true,
|
|
scope: {
|
|
parameters: '=',
|
|
syncValues: '=?',
|
|
editable: '=?',
|
|
changed: '&onChange',
|
|
onUpdated: '=',
|
|
onValuesChange: '=',
|
|
applyOnKeyboardShortcut: '<?',
|
|
},
|
|
template,
|
|
link(scope, $element) {
|
|
const el = $element.get(0);
|
|
const shortcuts = {
|
|
'mod+enter': () => scope.onApply(),
|
|
'alt+enter': () => scope.onApply(),
|
|
};
|
|
|
|
const onFocus = () => { KeyboardShortcuts.bind(shortcuts); };
|
|
const onBlur = () => { KeyboardShortcuts.unbind(shortcuts); };
|
|
|
|
el.addEventListener('focus', onFocus, true);
|
|
el.addEventListener('blur', onBlur, true);
|
|
|
|
scope.$on('$destroy', () => {
|
|
KeyboardShortcuts.unbind(shortcuts);
|
|
el.removeEventListener('focus', onFocus);
|
|
el.removeEventListener('blur', onBlur);
|
|
});
|
|
|
|
// is this the correct location for this logic?
|
|
if (scope.syncValues !== false) {
|
|
scope.$watch(
|
|
'parameters',
|
|
() => {
|
|
if (scope.changed) {
|
|
scope.changed({});
|
|
}
|
|
const params = extend({}, $location.search());
|
|
scope.parameters.forEach((param) => {
|
|
extend(params, param.toUrlParams());
|
|
});
|
|
Object.keys(params).forEach(key => params[key] == null && delete params[key]);
|
|
$location.search(params);
|
|
},
|
|
true,
|
|
);
|
|
}
|
|
|
|
scope.showParameterSettings = (parameter, index) => {
|
|
EditParameterSettingsDialog
|
|
.showModal({ parameter })
|
|
.result.then((updated) => {
|
|
scope.parameters[index] = extend(parameter, updated).setValue(updated.value);
|
|
scope.onUpdated();
|
|
});
|
|
};
|
|
|
|
scope.dirtyParamCount = 0;
|
|
scope.$watch(
|
|
'parameters',
|
|
() => {
|
|
scope.dirtyParamCount = size(filter(scope.parameters, 'hasPendingValue'));
|
|
},
|
|
true,
|
|
);
|
|
|
|
scope.isApplying = false;
|
|
scope.applyChanges = () => {
|
|
scope.isApplying = true;
|
|
forEach(scope.parameters, p => p.applyPendingValue());
|
|
scope.isApplying = false;
|
|
};
|
|
|
|
scope.onApply = () => {
|
|
if (!scope.dirtyParamCount) {
|
|
return false; // so keyboard shortcut doesn't run needlessly
|
|
}
|
|
|
|
scope.$apply(scope.applyChanges);
|
|
scope.onValuesChange();
|
|
};
|
|
},
|
|
};
|
|
}
|
|
|
|
export default function init(ngModule) {
|
|
ngModule.directive('parameters', ParametersDirective);
|
|
}
|
|
|
|
init.init = true;
|