Angular: Adds back two angular directives that are still used by remaining angular bits and plugins (#50380)

This commit is contained in:
Torkel Ödegaard 2022-06-08 10:34:58 +02:00 committed by GitHub
parent fd408652dc
commit 288eede638
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 237 additions and 111 deletions

View File

@ -0,0 +1,59 @@
import angular from 'angular';
import $ from 'jquery';
import coreModule from './core_module';
coreModule.directive('bsTooltip', [
'$parse',
'$compile',
function ($parse: any, $compile: any) {
return {
restrict: 'A',
scope: true,
link: function postLink(scope: any, element: any, attrs: any) {
var getter = $parse(attrs.bsTooltip),
value = getter(scope);
scope.$watch(attrs.bsTooltip, function (newValue: any, oldValue: any) {
if (newValue !== oldValue) {
value = newValue;
}
});
// Grafana change, always hide other tooltips
if (true) {
element.on('show', function (ev: any) {
$('.tooltip.in').each(function () {
var $this = $(this),
tooltip = $this.data('tooltip');
if (tooltip && !tooltip.$element.is(element)) {
$this.tooltip('hide');
}
});
});
}
element.tooltip({
title: function () {
return angular.isFunction(value) ? value.apply(null, arguments) : value;
},
html: true,
container: 'body', // Grafana change
});
var tooltip = element.data('tooltip');
tooltip.show = function () {
var r = $.fn.tooltip.Constructor.prototype.show.apply(this, arguments);
this.tip().data('tooltip', this);
return r;
};
scope._tooltip = function (event: any) {
element.tooltip(event);
};
scope.hide = function () {
element.tooltip('hide');
};
scope.show = function () {
element.tooltip('show');
};
scope.dismiss = scope.hide;
},
};
},
]);

View File

@ -0,0 +1,63 @@
import angular from 'angular';
import $ from 'jquery';
import { isFunction } from 'lodash';
import coreModule from './core_module';
coreModule.directive('bsTypeahead', [
'$parse',
function ($parse: any) {
return {
restrict: 'A',
require: '?ngModel',
link: function postLink(scope: any, element: any, attrs: any, controller: any) {
var getter = $parse(attrs.bsTypeahead),
value = getter(scope);
scope.$watch(attrs.bsTypeahead, function (newValue: any, oldValue: any) {
if (newValue !== oldValue) {
value = newValue;
}
});
element.attr('data-provide', 'typeahead');
element.typeahead({
source: function () {
return angular.isFunction(value) ? value.apply(null, arguments) : value;
},
minLength: attrs.minLength || 1,
items: attrs.item,
updater: function (value: any) {
if (controller) {
scope.$apply(function () {
controller.$setViewValue(value);
});
}
scope.$emit('typeahead-updated', value);
return value;
},
});
var typeahead = element.dat('typeahead');
typeahead.lookup = function (ev: any) {
var items;
this.query = this.$element.val() || '';
if (this.query.length < this.options.minLength) {
return this.shown ? this.hide() : this;
}
items = isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source;
return items ? this.process(items) : this;
};
if (!!attrs.matchAll) {
typeahead.matcher = function () {
return true;
};
}
if (attrs.minLength === '0') {
setTimeout(function () {
element.on('focus', function () {
element.val().length === 0 && setTimeout(element.typeahead.bind(element, 'lookup'), 200);
});
});
}
},
};
},
]);

View File

@ -14,6 +14,8 @@ import './dropdown_typeahead';
import './autofill_event_fix';
import './metric_segment';
import './misc';
import './bsTooltip';
import './bsTypeahead';
import './ng_model_on_blur';
import './tags';
import './rebuild_on_change';

View File

@ -1,25 +1,30 @@
<h3 class="page-heading">MS SQL connection</h3>
<div class="gf-form-group">
<div class="gf-form max-width-30">
<span class="gf-form-label width-7">Host</span>
<input type="text" class="gf-form-input" style="width: 352px" ng-model='ctrl.current.url' placeholder="localhost" bs-typeahead="{{['localhost', 'localhost" required></input>
<input type="text" class="gf-form-input" style="width: 352px" ng-model='ctrl.current.url' placeholder="localhost"
bs-typeahead="{{['localhost', 'localhost:1433']}}" required></input>
</div>
<div class="gf-form max-width-30">
<span class="gf-form-label width-7">Database</span>
<input type="text" class="gf-form-input" style="width: 352px" ng-model='ctrl.current.database' placeholder="database name" required></input>
<input type="text" class="gf-form-input" style="width: 352px" ng-model='ctrl.current.database'
placeholder="database name" required></input>
</div>
<div class="gf-form">
<label class="gf-form-label width-7" for="auth-select">Authentication</label>
<div class="gf-form-select-wrapper max-width-15 gf-form-select-wrapper--has-help-icon">
<select id="auth-select" class="gf-form-input" ng-model="ctrl.current.jsonData.authenticationType" ng-options="mode for mode in ['Windows Authentication', 'SQL Server Authentication']" ng-init="ctrl.current.jsonData.authenticationType" ng-change="ctrl.onAuthenticationTypeChange()"></select>
<select id="auth-select" class="gf-form-input" ng-model="ctrl.current.jsonData.authenticationType"
ng-options="mode for mode in ['Windows Authentication', 'SQL Server Authentication']"
ng-init="ctrl.current.jsonData.authenticationType" ng-change="ctrl.onAuthenticationTypeChange()"></select>
<info-popover mode="right-absolute">
<ul>
<li><i>SQL Server Authentication</i> This is the default mechanism to connect to MS SQL Server. Enter the SQL Server Authentication login or the Windows Authentication login in the DOMAIN\User format.</li>
<li><i>Windows Authentication</i> Windows Integrated Security - single sign on for users who are already logged onto Windows and have enabled this option for MS SQL Server.</li>
<li><i>SQL Server Authentication</i> This is the default mechanism to connect to MS SQL Server. Enter the SQL
Server Authentication login or the Windows Authentication login in the DOMAIN\User format.</li>
<li><i>Windows Authentication</i> Windows Integrated Security - single sign on for users who are already
logged onto Windows and have enabled this option for MS SQL Server.</li>
</ul>
</info-popover>
</div>
@ -30,15 +35,9 @@
<input type="text" class="gf-form-input" ng-model='ctrl.current.user' placeholder="user"></input>
</div>
<div class="gf-form">
<secret-form-field
isConfigured="ctrl.current.secureJsonFields.password"
value="ctrl.current.secureJsonData.password"
on-reset="ctrl.onPasswordReset"
on-change="ctrl.onPasswordChange"
labelWidth="7"
inputWidth="7"
aria-label="'Password'"
/>
<secret-form-field isConfigured="ctrl.current.secureJsonFields.password"
value="ctrl.current.secureJsonData.password" on-reset="ctrl.onPasswordReset" on-change="ctrl.onPasswordChange"
labelWidth="7" inputWidth="7" aria-label="'Password'" />
</div>
</div>
@ -51,15 +50,19 @@
<div class="gf-form">
<label class="gf-form-label width-15" for="encrypt-select">Encrypt</label>
<div class="gf-form-select-wrapper max-width-15 gf-form-select-wrapper--has-help-icon">
<select id="encrypt-select" class="gf-form-input" ng-model="ctrl.current.jsonData.encrypt" ng-options="mode for mode in ['disable', 'false', 'true']" ng-init="ctrl.current.jsonData.encrypt" ng-change="ctrl.onEncryptChange()" aria-labelledby="encrypt-label"></select>
<select id="encrypt-select" class="gf-form-input" ng-model="ctrl.current.jsonData.encrypt"
ng-options="mode for mode in ['disable', 'false', 'true']" ng-init="ctrl.current.jsonData.encrypt"
ng-change="ctrl.onEncryptChange()" aria-labelledby="encrypt-label"></select>
<info-popover mode="right-absolute">
Determines whether or to which extent a secure SSL TCP/IP connection will be negotiated with the server.
<ul>
<li><i>disable</i> - Data sent between client and server is not encrypted.</li>
<li><i>false</i> - Data sent between client and server is not encrypted beyond the login packet. (default)</li>
<li><i>false</i> - Data sent between client and server is not encrypted beyond the login packet. (default)
</li>
<li><i>true</i> - Data sent between client and server is encrypted.</li>
</ul>
If you're using an older version of Microsoft SQL Server like 2008 and 2008R2 you may need to disable encryption to be able to connect.
If you're using an older version of Microsoft SQL Server like 2008 and 2008R2 you may need to disable encryption
to be able to connect.
</info-popover>
</div>
</div>
@ -67,8 +70,8 @@
<div class="gf-form" ng-show="ctrl.showTlsConfig">
<gf-form-switch class="gf-form" label="Skip TLS/SSL Verify" label-class="width-15"
tooltip="Skip verifying Server Certificate for TLS/SSL. If this is enabled, any certificate presented by the server and any host name in that certificate will be accepted. In this mode, TLS is susceptible to man-in-the-middle attacks. This should be used only for testing."
checked="ctrl.current.jsonData.tlsSkipVerify" switch-class="max-width-8"
on-change="ctrl.onEncryptChange()"></gf-form-switch>
checked="ctrl.current.jsonData.tlsSkipVerify" switch-class="max-width-8" on-change="ctrl.onEncryptChange()">
</gf-form-switch>
</div>
<div class="gf-form max-width-30" ng-show="ctrl.showCertificateConfig">
@ -97,7 +100,8 @@
<div class="gf-form-group">
<div class="gf-form max-width-15">
<span class="gf-form-label width-7">Max open</span>
<input type="number" min="0" class="gf-form-input gf-form-input--has-help-icon" ng-model="ctrl.current.jsonData.maxOpenConns" placeholder="unlimited"></input>
<input type="number" min="0" class="gf-form-input gf-form-input--has-help-icon"
ng-model="ctrl.current.jsonData.maxOpenConns" placeholder="unlimited"></input>
<info-popover mode="right-absolute">
The maximum number of open connections to the database. If <i>Max idle connections</i> is greater than 0 and the
<i>Max open connections</i> is less than <i>Max idle connections</i>, then <i>Max idle connections</i> will be
@ -107,16 +111,19 @@
</div>
<div class="gf-form max-width-15">
<span class="gf-form-label width-7">Max idle</span>
<input type="number" min="0" class="gf-form-input gf-form-input--has-help-icon" ng-model="ctrl.current.jsonData.maxIdleConns" placeholder="2"></input>
<input type="number" min="0" class="gf-form-input gf-form-input--has-help-icon"
ng-model="ctrl.current.jsonData.maxIdleConns" placeholder="2"></input>
<info-popover mode="right-absolute">
The maximum number of connections in the idle connection pool. If <i>Max open connections</i> is greater than 0 but
The maximum number of connections in the idle connection pool. If <i>Max open connections</i> is greater than 0
but
less than the <i>Max idle connections</i>, then the <i>Max idle connections</i> will be reduced to match the
<i>Max open connections</i> limit. If set to 0, no idle connections are retained.
</info-popover>
</div>
<div class="gf-form max-width-15">
<span class="gf-form-label width-7">Max lifetime</span>
<input type="number" min="0" class="gf-form-input gf-form-input--has-help-icon" ng-model="ctrl.current.jsonData.connMaxLifetime" placeholder="14400"></input>
<input type="number" min="0" class="gf-form-input gf-form-input--has-help-icon"
ng-model="ctrl.current.jsonData.connMaxLifetime" placeholder="14400"></input>
<info-popover mode="right-absolute">
The maximum amount of time in seconds a connection may be reused. If set to 0, connections are reused forever.
</info-popover>
@ -129,14 +136,9 @@
<div class="gf-form-inline">
<div class="gf-form">
<span class="gf-form-label width-9">Min time interval</span>
<input
type="text"
class="gf-form-input width-6 gf-form-input--has-help-icon"
ng-model="ctrl.current.jsonData.timeInterval"
spellcheck='false'
placeholder="1m"
ng-pattern="/^\d+(ms|[Mwdhmsy])$/"
></input>
<input type="text" class="gf-form-input width-6 gf-form-input--has-help-icon"
ng-model="ctrl.current.jsonData.timeInterval" spellcheck='false' placeholder="1m"
ng-pattern="/^\d+(ms|[Mwdhmsy])$/"></input>
<info-popover mode="right-absolute">
A lower limit for the auto group by time interval. Recommended to be set to write frequency,
for example <code>1m</code> if your data is written every minute.
@ -149,11 +151,11 @@
<div class="grafana-info-box">
<h5>User Permission</h5>
<p>
The database user should only be granted SELECT permissions on the specified database and tables you want to query.
The database user should only be granted SELECT permissions on the specified database and tables you want to
query.
Grafana does not validate that queries are safe so queries can contain any SQL statement. For example, statements
like <code>USE otherdb;</code> and <code>DROP TABLE user;</code> would be executed. To protect against this we
<emphasis>highly</emphasis> recommmend you create a specific MS SQL user with restricted permissions.
</p>
</div>
</div>