diff --git a/.circleci/config.yml b/.circleci/config.yml index 1b713003a3895..e7c69e8baf56b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,7 +12,7 @@ aliases: ignore: master - &filter-only-master branches: - only: master + only: masterXXX # never match... for Natel version: 2 @@ -276,7 +276,7 @@ jobs: command: '/tmp/bootstrap.sh' - run: name: package grafana - command: './scripts/build/build.sh --fast --package-only' + command: './scripts/build/build-all.sh' - run: name: sha-sum packages command: 'go run build.go sha-dist' diff --git a/emails/templates/layouts/default.html b/emails/templates/layouts/default.html index ca54acdd2060c..c6b433c6cbc75 100644 --- a/emails/templates/layouts/default.html +++ b/emails/templates/layouts/default.html @@ -107,7 +107,7 @@ @@ -143,7 +143,7 @@

Sent by Grafana v[[.BuildVersion]] -
© 2018 Grafana Labs +
© 2019 Natel Energy

diff --git a/package.json b/package.json index c7cc8a83644eb..39176751e2c7e 100644 --- a/package.json +++ b/package.json @@ -199,6 +199,7 @@ "calculate-size": "1.1.1", "classnames": "2.2.6", "clipboard": "2.0.4", + "css-element-queries": "^1.1.1", "d3": "4.13.0", "d3-scale-chromatic": "1.3.3", "eventemitter3": "2.0.3", diff --git a/pkg/api/login_oauth.go b/pkg/api/login_oauth.go index 8c5ca6fc7d1d2..1f5a4e14e2ee9 100644 --- a/pkg/api/login_oauth.go +++ b/pkg/api/login_oauth.go @@ -71,6 +71,18 @@ func (hs *HTTPServer) OAuthLogin(ctx *m.ReqContext) { cookieState := ctx.GetCookie(OauthStateCookieName) + // https://github.com/grafana/grafana/pull/7046 + if cookieState == "" { + if ctx.Query("redirected") == "yes" { + //ctx.Handle(500, "login.OAuthLogin(missing saved state) after redirect", nil) + ctx.Redirect(setting.AppUrl) + return + } + loc := setting.AppUrl + "login/" + name + "?" + ctx.Req.URL.RawQuery + "&redirected=yes" + ctx.Redirect(loc) + return + } + // delete cookie ctx.Resp.Header().Del("Set-Cookie") hs.deleteCookie(ctx.Resp, OauthStateCookieName) diff --git a/pkg/login/social/social.go b/pkg/login/social/social.go index 46192ba861e07..292a7fd822542 100644 --- a/pkg/login/social/social.go +++ b/pkg/login/social/social.go @@ -81,6 +81,7 @@ func NewOAuthService() { TlsClientCa: sec.Key("tls_client_ca").String(), TlsSkipVerify: sec.Key("tls_skip_verify_insecure").MustBool(), SendClientCredentialsViaPost: sec.Key("send_client_credentials_via_post").MustBool(), + RedirectUrl: sec.Key("redirect_url").String(), } if !info.Enabled { @@ -105,7 +106,7 @@ func NewOAuthService() { AuthURL: info.AuthUrl, TokenURL: info.TokenUrl, }, - RedirectURL: strings.TrimSuffix(setting.AppUrl, "/") + SocialBaseUrl + name, + RedirectURL: info.RedirectUrl, Scopes: info.Scopes, } @@ -192,6 +193,10 @@ func NewOAuthService() { allowedOrganizations: util.SplitString(sec.Key("allowed_organizations").String()), } } + + if len(config.RedirectURL) == 0 { + config.RedirectURL = strings.TrimSuffix(setting.AppUrl, "/") + SocialBaseUrl + name + } } } diff --git a/pkg/setting/setting_oauth.go b/pkg/setting/setting_oauth.go index f0a3beccb4499..21d888a5468ba 100644 --- a/pkg/setting/setting_oauth.go +++ b/pkg/setting/setting_oauth.go @@ -4,6 +4,7 @@ type OAuthInfo struct { ClientId, ClientSecret string Scopes []string AuthUrl, TokenUrl string + RedirectUrl string Enabled bool EmailAttributeName string AllowedDomains []string diff --git a/public/app/core/components/Footer/Footer.tsx b/public/app/core/components/Footer/Footer.tsx index 45f7cc71131ca..3aa19a0426a06 100644 --- a/public/app/core/components/Footer/Footer.tsx +++ b/public/app/core/components/Footer/Footer.tsx @@ -1,5 +1,4 @@ import React, { FC } from 'react'; -import { Tooltip } from '@grafana/ui'; interface Props { appName: string; @@ -16,37 +15,15 @@ export const Footer: FC = React.memo(
diff --git a/public/app/core/components/OrgActionBar/OrgActionBar.tsx b/public/app/core/components/OrgActionBar/OrgActionBar.tsx index 016c477766863..5753240111b49 100644 --- a/public/app/core/components/OrgActionBar/OrgActionBar.tsx +++ b/public/app/core/components/OrgActionBar/OrgActionBar.tsx @@ -14,7 +14,7 @@ export interface Props { export default class OrgActionBar extends PureComponent { render() { const { searchQuery, layoutMode, onSetLayoutMode, linkButton, setSearchQuery, target } = this.props; - const linkProps = { href: linkButton.href }; + const linkProps = { href: linkButton ? linkButton.href : '#' }; if (target) { (linkProps as any).target = target; @@ -33,9 +33,11 @@ export default class OrgActionBar extends PureComponent { onSetLayoutMode(mode)} /> ); } diff --git a/public/app/features/admin/__snapshots__/ServerStats.test.tsx.snap b/public/app/features/admin/__snapshots__/ServerStats.test.tsx.snap index bb1ba9c9388f8..68f06dcc60cb2 100644 --- a/public/app/features/admin/__snapshots__/ServerStats.test.tsx.snap +++ b/public/app/features/admin/__snapshots__/ServerStats.test.tsx.snap @@ -159,35 +159,13 @@ exports[`ServerStats Should render table with stats 1`] = `
  • - Docs - -
  • -
  • - - - Support Plans - -
  • -
  • - - - Community + Upstream Tech
  • diff --git a/public/app/features/dashboard/services/ChangeTracker.ts b/public/app/features/dashboard/services/ChangeTracker.ts index 7fe365cd8e004..f5f125e6cf432 100644 --- a/public/app/features/dashboard/services/ChangeTracker.ts +++ b/public/app/features/dashboard/services/ChangeTracker.ts @@ -110,6 +110,7 @@ export class ChangeTracker { // ignore iteration property delete dash.iteration; + let hasDynamicHeight = false; dash.panels = _.filter(dash.panels, panel => { if (panel.repeatPanelId) { return false; @@ -124,6 +125,15 @@ export class ChangeTracker { delete panel.legend.sortDesc; } + // ignore all y parameters after a dynamic height + if (panel.dynamicHeight) { + hasDynamicHeight = true; + delete panel.gridPos.h; + } + if (hasDynamicHeight) { + delete panel.gridPos.y; + } + return true; }); diff --git a/public/app/features/panel/panel_ctrl.ts b/public/app/features/panel/panel_ctrl.ts index cf110cdc705b6..b1898c40f1854 100644 --- a/public/app/features/panel/panel_ctrl.ts +++ b/public/app/features/panel/panel_ctrl.ts @@ -14,7 +14,7 @@ import { calculateInnerPanelHeight, } from 'app/features/dashboard/utils/panel'; -import { GRID_COLUMN_COUNT } from 'app/core/constants'; +import { GRID_COLUMN_COUNT, GRID_CELL_HEIGHT, GRID_CELL_VMARGIN } from 'app/core/constants'; export class PanelCtrl { panel: any; @@ -63,6 +63,25 @@ export class PanelCtrl { profiler.renderingCompleted(); } + dynamicHeightChanged(height: number): boolean { + const min = this.panel.dynamicHeightMIN || 50; + if (height < min) { + height = min; + } + if (this.panel.dynamicHeightMAX && height > this.panel.dynamicHeightMAX) { + height = this.panel.dynamicHeightMAX; + } + const h = Math.ceil((height + 5) / (GRID_CELL_HEIGHT + GRID_CELL_VMARGIN)) + 1; + if (h !== this.panel.gridPos.h) { + //console.log('Dynamic Height Changed', height, 'new:', h, 'old', this.panel.gridPos.h); + this.panel.gridPos.h = h; + this.events.emit('panel-size-changed'); + this.dashboard.events.emit('row-expanded'); // triggers grid re-layout + return true; + } + return false; + } + refresh() { this.panel.refresh(); } diff --git a/public/app/features/panel/panel_directive.ts b/public/app/features/panel/panel_directive.ts index 8cfc627b424b6..6fe45d666616c 100644 --- a/public/app/features/panel/panel_directive.ts +++ b/public/app/features/panel/panel_directive.ts @@ -2,6 +2,7 @@ import angular from 'angular'; import $ from 'jquery'; import Drop from 'tether-drop'; import baron from 'baron'; +import ResizeSensor from 'css-element-queries/src/ResizeSensor.js'; const module = angular.module('grafana.directives'); @@ -40,6 +41,8 @@ module.directive('grafanaPanel', ($rootScope, $document, $timeout) => { const ctrl = scope.ctrl; let infoDrop; let panelScrollbar; + let panelInnerContent; + let panelInnerContentHeight = -1; // the reason for handling these classes this way is for performance // limit the watchers on panels etc @@ -58,6 +61,16 @@ module.directive('grafanaPanel', ($rootScope, $document, $timeout) => { ctrl.dashboard.setPanelFocus(0); } + function checkInnerContentHeight() { + if (ctrl.panel.dynamicHeight && panelInnerContent) { + const v = panelInnerContent.outerHeight(true); + if (v !== panelInnerContentHeight) { + panelInnerContentHeight = v; + ctrl.dynamicHeightChanged(panelInnerContentHeight); + } + } + } + function resizeScrollableContent() { if (panelScrollbar) { panelScrollbar.update(); @@ -82,7 +95,21 @@ module.directive('grafanaPanel', ($rootScope, $document, $timeout) => { `; const scrollRoot = panelContent; - const scroller = panelContent.find(':first').find(':first'); + let scroller = panelContent.find(':first').find(':first'); + + // Add a div under the scroller and watch for changes + if (ctrl.panel.dynamicHeight) { + $(scroller).wrap('
    '); + scroller = panelContent.find(':first'); + + panelInnerContent = $(scroller).find(':first'); + panelInnerContent.removeClass('panel-height-helper'); + panelInnerContent.css('margin-right', '20px'); + // panelInnerContent.css('border', '2px solid #F0F'); + + // tslint:disable-next-line + new ResizeSensor(panelInnerContent, checkInnerContentHeight); + } scrollRoot.addClass(scrollRootClass); $(scrollBarHTML).appendTo(scrollRoot); diff --git a/public/app/features/panel/partials/general_tab.html b/public/app/features/panel/partials/general_tab.html index ceae445f3ed88..2573129ff72b9 100644 --- a/public/app/features/panel/partials/general_tab.html +++ b/public/app/features/panel/partials/general_tab.html @@ -52,3 +52,21 @@ + + +
    +
    Height
    +
    + +
    + Minimum + +
    +
    + Maximum + +
    +
    +
    + + diff --git a/public/app/features/plugins/PluginListPage.tsx b/public/app/features/plugins/PluginListPage.tsx index 03d383fdec0ca..911cde2ebdf6e 100644 --- a/public/app/features/plugins/PluginListPage.tsx +++ b/public/app/features/plugins/PluginListPage.tsx @@ -41,11 +41,6 @@ export class PluginListPage extends PureComponent { searchQuery, } = this.props; - const linkButton = { - href: 'https://grafana.com/plugins?utm_source=grafana_plugin_list', - title: 'Find more plugins on Grafana.com', - }; - return ( @@ -55,7 +50,7 @@ export class PluginListPage extends PureComponent { layoutMode={layoutMode} onSetLayoutMode={mode => setPluginsLayoutMode(mode)} setSearchQuery={query => setPluginsSearchQuery(query)} - linkButton={linkButton} + linkButton={null} /> {hasFetched && plugins && (plugins && )} diff --git a/public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap b/public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap deleted file mode 100644 index eab70367152e8..0000000000000 --- a/public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap +++ /dev/null @@ -1,69 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Render should render component 1`] = ` - - - - - -`; - -exports[`Render should render list 1`] = ` - - - - - - -`; diff --git a/public/app/features/plugins/plugin_loader.ts b/public/app/features/plugins/plugin_loader.ts index 2ee31a7b6aa26..290d118d44c14 100644 --- a/public/app/features/plugins/plugin_loader.ts +++ b/public/app/features/plugins/plugin_loader.ts @@ -18,7 +18,7 @@ import reactDom from 'react-dom'; import config from 'app/core/config'; import TimeSeries from 'app/core/time_series2'; import TableModel from 'app/core/table_model'; -import { coreModule, appEvents, contextSrv } from 'app/core/core'; +import { coreModule, appEvents, contextSrv, Emitter } from 'app/core/core'; import { DataSourcePlugin, AppPlugin, PanelPlugin, PluginMeta, DataSourcePluginMeta } from '@grafana/ui/src/types'; import * as datemath from '@grafana/ui/src/utils/datemath'; import * as fileExport from 'app/core/utils/file_export'; @@ -122,6 +122,7 @@ exposeToPlugin('app/core/core', { coreModule: coreModule, appEvents: appEvents, contextSrv: contextSrv, + Emitter: Emitter, __esModule: true, }); diff --git a/public/app/routes/GrafanaCtrl.ts b/public/app/routes/GrafanaCtrl.ts index a37222091d050..ed8efe3e08594 100644 --- a/public/app/routes/GrafanaCtrl.ts +++ b/public/app/routes/GrafanaCtrl.ts @@ -52,6 +52,14 @@ export class GrafanaCtrl { bridgeSrv.init(); }; + // Export services to plugins via window + (window as any).grafanaRuntime = { + angularLoader, + backendSrv, + datasourceSrv, + timeSrv, + }; + $rootScope.colors = colors; $rootScope.onAppEvent = function(name, callback, localScope) { diff --git a/public/img/grafana_icon.svg b/public/img/grafana_icon.svg index 72702223dc77b..5eb8fef4e65e1 100644 --- a/public/img/grafana_icon.svg +++ b/public/img/grafana_icon.svg @@ -1,57 +1,2 @@ - - - - - - - - - - - - + + diff --git a/public/sass/layout/_page.scss b/public/sass/layout/_page.scss index 6b2fa95730e0a..edcefa44e82db 100644 --- a/public/sass/layout/_page.scss +++ b/public/sass/layout/_page.scss @@ -41,7 +41,7 @@ margin-right: auto; padding-left: $spacer * 2; padding-right: $spacer * 2; - max-width: 980px; + max-width: 100%; @include clearfix(); } diff --git a/public/views/index-template.html b/public/views/index-template.html index fa19ae599dd20..1e5a582415f4f 100644 --- a/public/views/index-template.html +++ b/public/views/index-template.html @@ -198,34 +198,16 @@
    diff --git a/scripts/grunt/options/exec.js b/scripts/grunt/options/exec.js index 3296abecfd4a9..fa983e426ba5c 100644 --- a/scripts/grunt/options/exec.js +++ b/scripts/grunt/options/exec.js @@ -18,7 +18,7 @@ module.exports = function(config, grunt) { command: 'yarn run typecheck', src: ['public/app/**/*.ts*'], }, - jest: 'node ./node_modules/jest-cli/bin/jest.js --maxWorkers 2', + jest: 'node ./node_modules/jest-cli/bin/jest.js --updateSnapshot --maxWorkers 2', webpack: 'node ./node_modules/webpack/bin/webpack.js --config scripts/webpack/webpack.prod.js', }; diff --git a/yarn.lock b/yarn.lock index 1710b7e87102a..06dd13cde7c71 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5366,6 +5366,11 @@ css-declaration-sorter@^4.0.1: postcss "^7.0.1" timsort "^0.3.0" +css-element-queries@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/css-element-queries/-/css-element-queries-1.1.1.tgz#129e104ecb277aa6337b7302cbb6d511c2d1633a" + integrity sha512-/PX6Bkk77ShgbOx/mpawHdEvS3PGgy1mmMktcztDPndWdMJxcorcQiivrs+nEljqtBpvNEhAmQky9tQR6FSm8Q== + css-loader@2.1.1, css-loader@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-2.1.1.tgz#d8254f72e412bb2238bb44dd674ffbef497333ea"
- +