diff --git a/docs/sources/auth/overview.md b/docs/sources/auth/overview.md index d4360d554c1..0480ee88adc 100644 --- a/docs/sources/auth/overview.md +++ b/docs/sources/auth/overview.md @@ -78,8 +78,8 @@ disable_login_form = true ### Automatic OAuth login -Set to true to attempt login with OAuth automatically, skipping the login screen. -This setting is ignored if multiple OAuth providers are configured. +Set to true to attempt login with OAuth automatically, skipping the login screen. +This setting is ignored if multiple OAuth providers are configured. Defaults to `false`. ```bash @@ -95,3 +95,12 @@ Set to the option detailed below to true to hide sign-out menu link. Useful if y [auth] disable_signout_menu = true ``` + +### URL redirect after signing out + +URL to redirect the user to after signing out from Grafana. This can for example be used to enable signout from oauth provider. + +```bash +[auth] +signout_redirect_url = +``` diff --git a/public/app/core/utils/kbn.ts b/public/app/core/utils/kbn.ts index 398ad9bb3e7..5d417d24169 100644 --- a/public/app/core/utils/kbn.ts +++ b/public/app/core/utils/kbn.ts @@ -584,8 +584,8 @@ kbn.valueFormats.flowcms = kbn.formatBuilders.fixedUnit('cms'); kbn.valueFormats.flowcfs = kbn.formatBuilders.fixedUnit('cfs'); kbn.valueFormats.flowcfm = kbn.formatBuilders.fixedUnit('cfm'); kbn.valueFormats.litreh = kbn.formatBuilders.fixedUnit('l/h'); -kbn.valueFormats.flowlpm = kbn.formatBuilders.decimalSIPrefix('L'); -kbn.valueFormats.flowmlpm = kbn.formatBuilders.decimalSIPrefix('L', -1); +kbn.valueFormats.flowlpm = kbn.formatBuilders.decimalSIPrefix('l/min'); +kbn.valueFormats.flowmlpm = kbn.formatBuilders.decimalSIPrefix('mL/min', -1); // Angle kbn.valueFormats.degree = kbn.formatBuilders.fixedUnit('°'); diff --git a/public/app/features/explore/Typeahead.tsx b/public/app/features/explore/Typeahead.tsx index 13882e030f6..721527fbebe 100644 --- a/public/app/features/explore/Typeahead.tsx +++ b/public/app/features/explore/Typeahead.tsx @@ -42,7 +42,7 @@ class TypeaheadItem extends React.PureComponent { render() { const { isSelected, item, prefix } = this.props; const className = isSelected ? 'typeahead-item typeahead-item__selected' : 'typeahead-item'; - const { label } = item; + const label = item.label || ''; return (
  • diff --git a/public/app/plugins/datasource/logging/language_provider.test.ts b/public/app/plugins/datasource/logging/language_provider.test.ts index 79f696843bb..f4fc7efa7cb 100644 --- a/public/app/plugins/datasource/logging/language_provider.test.ts +++ b/public/app/plugins/datasource/logging/language_provider.test.ts @@ -95,5 +95,14 @@ describe('Query imports', () => { const result = await instance.importPrometheusQuery('metric{foo="bar",baz="42"}'); expect(result).toEqual('{foo="bar"}'); }); + + it('returns selector query from selector query with all labels if logging label list is empty', async () => { + const datasourceWithLabels = { + metadataRequest: url => (url === '/api/prom/label' ? { data: { data: [] } } : { data: { data: [] } }), + }; + const instance = new LanguageProvider(datasourceWithLabels); + const result = await instance.importPrometheusQuery('metric{foo="bar",baz="42"}'); + expect(result).toEqual('{baz="42",foo="bar"}'); + }); }); }); diff --git a/public/app/plugins/datasource/logging/language_provider.ts b/public/app/plugins/datasource/logging/language_provider.ts index eb47b3b1e27..21d2846ac63 100644 --- a/public/app/plugins/datasource/logging/language_provider.ts +++ b/public/app/plugins/datasource/logging/language_provider.ts @@ -97,9 +97,10 @@ export default class LoggingLanguageProvider extends LanguageProvider { if (history && history.length > 0) { const historyItems = _.chain(history) - .uniqBy('query.expr') - .take(HISTORY_ITEM_COUNT) .map(h => h.query.expr) + .filter() + .uniq() + .take(HISTORY_ITEM_COUNT) .map(wrapLabel) .map(item => addHistoryMetadata(item, history)) .value(); @@ -194,17 +195,24 @@ export default class LoggingLanguageProvider extends LanguageProvider { // Keep only labels that exist on origin and target datasource await this.start(); // fetches all existing label keys - const commonLabels = {}; - for (const key in labels) { - const existingKeys = this.labelKeys[EMPTY_SELECTOR]; - if (existingKeys && existingKeys.indexOf(key) > -1) { - // Should we check for label value equality here? - commonLabels[key] = labels[key]; + const existingKeys = this.labelKeys[EMPTY_SELECTOR]; + let labelsToKeep = {}; + if (existingKeys && existingKeys.length > 0) { + // Check for common labels + for (const key in labels) { + if (existingKeys && existingKeys.indexOf(key) > -1) { + // Should we check for label value equality here? + labelsToKeep[key] = labels[key]; + } } + } else { + // Keep all labels by default + labelsToKeep = labels; } - const labelKeys = Object.keys(commonLabels).sort(); + + const labelKeys = Object.keys(labelsToKeep).sort(); const cleanSelector = labelKeys - .map(key => `${key}${commonLabels[key].operator}${commonLabels[key].value}`) + .map(key => `${key}${labelsToKeep[key].operator}${labelsToKeep[key].value}`) .join(','); return ['{', cleanSelector, '}'].join(''); diff --git a/public/app/plugins/datasource/prometheus/language_provider.ts b/public/app/plugins/datasource/prometheus/language_provider.ts index 5fd8fcebaaf..d7ccead8725 100644 --- a/public/app/plugins/datasource/prometheus/language_provider.ts +++ b/public/app/plugins/datasource/prometheus/language_provider.ts @@ -125,9 +125,10 @@ export default class PromQlLanguageProvider extends LanguageProvider { if (history && history.length > 0) { const historyItems = _.chain(history) - .uniqBy('query.expr') - .take(HISTORY_ITEM_COUNT) .map(h => h.query.expr) + .filter() + .uniq() + .take(HISTORY_ITEM_COUNT) .map(wrapLabel) .map(item => addHistoryMetadata(item, history)) .value(); diff --git a/public/sass/components/_footer.scss b/public/sass/components/_footer.scss index 9bc99c30d1d..893eea02914 100644 --- a/public/sass/components/_footer.scss +++ b/public/sass/components/_footer.scss @@ -4,7 +4,7 @@ .footer { color: $footer-link-color; - padding: 5rem 0 1rem 0; + padding: 1rem 0 1rem 0; font-size: $font-size-sm; position: relative; width: 98%; /* was causing horiz scrollbars - need to examine */ @@ -38,6 +38,7 @@ } } +// Keeping footer inside the graphic on Login screen .login-page { .footer { bottom: $spacer; diff --git a/public/sass/components/_gf-form.scss b/public/sass/components/_gf-form.scss index 48e886e4c93..3e0a13a187a 100644 --- a/public/sass/components/_gf-form.scss +++ b/public/sass/components/_gf-form.scss @@ -82,7 +82,7 @@ $input-border: 1px solid $input-border-color; align-content: flex-start; .gf-form + .gf-form { - margin-right: $gf-form-margin; + margin-left: $gf-form-margin; } } @@ -163,7 +163,6 @@ $input-border: 1px solid $input-border-color; width: 100%; height: $gf-form-input-height; padding: $input-padding-y $input-padding-x; - margin-right: $gf-form-margin; font-size: $font-size-md; line-height: $input-line-height; color: $input-color; diff --git a/public/sass/components/_query_editor.scss b/public/sass/components/_query_editor.scss index 9fcfdf719ba..40cee199062 100644 --- a/public/sass/components/_query_editor.scss +++ b/public/sass/components/_query_editor.scss @@ -35,7 +35,7 @@ } .gf-form + .gf-form { - margin-right: 0; + margin-left: 0; } } diff --git a/public/sass/layout/_page.scss b/public/sass/layout/_page.scss index faa5b94d4ad..312248086fa 100644 --- a/public/sass/layout/_page.scss +++ b/public/sass/layout/_page.scss @@ -40,6 +40,29 @@ &--dashboard { height: calc(100% - 56px); } + + // Sticky footer + display: flex; + flex-direction: column; + + > div { + flex-grow: 1; + } + + > .footer { + flex-shrink: 0; + } + + // Render in correct position even ng-view div is not rendered yet + > .footer:first-child { + flex-grow: 1; + display: flex; + + > * { + width: 100%; + align-self: flex-end; + } + } } // fix for phantomjs