From a2967565deb39f8633da1fb4d653c909f505b409 Mon Sep 17 00:00:00 2001 From: Benjamin Schweizer Date: Mon, 30 Jul 2018 17:19:41 +0200 Subject: [PATCH 01/32] added urlescape formatting option --- docs/sources/reference/templating.md | 1 + public/app/features/templating/specs/template_srv.jest.ts | 5 +++++ public/app/features/templating/template_srv.ts | 7 +++++++ 3 files changed, 13 insertions(+) diff --git a/docs/sources/reference/templating.md b/docs/sources/reference/templating.md index ce1a1299d26..d59117fefea 100644 --- a/docs/sources/reference/templating.md +++ b/docs/sources/reference/templating.md @@ -52,6 +52,7 @@ Filter Option | Example | Raw | Interpolated | Description `csv`| ${servers:csv} | `'test1', 'test2'` | `test1,test2` | Formats multi-value variable as a comma-separated string `distributed`| ${servers:distributed} | `'test1', 'test2'` | `test1,servers=test2` | Formats multi-value variable in custom format for OpenTSDB. `lucene`| ${servers:lucene} | `'test', 'test2'` | `("test" OR "test2")` | Formats multi-value variable as a lucene expression. +`urlescape` | ${servers:urlescape} | `'foo()bar baz', 'test2'` | `{foo%28%29bar%20baz%2Ctest2}` | Formats multi-value variable into a glob, url escaped Test the formatting options on the [Grafana Play site](http://play.grafana.org/d/cJtIfcWiz/template-variable-formatting-options?orgId=1). diff --git a/public/app/features/templating/specs/template_srv.jest.ts b/public/app/features/templating/specs/template_srv.jest.ts index 86b6aa7ec99..040597888b6 100644 --- a/public/app/features/templating/specs/template_srv.jest.ts +++ b/public/app/features/templating/specs/template_srv.jest.ts @@ -275,6 +275,11 @@ describe('templateSrv', function() { expect(result).toBe('test,test2'); }); + it('multi value and urlescape format should render url-escaped string', function() { + var result = _templateSrv.formatValue(['foo()bar baz', 'test2'], 'urlescape'); + expect(result).toBe('foo%28%29bar%20baz%2Ctest2'); + }); + it('slash should be properly escaped in regex format', function() { var result = _templateSrv.formatValue('Gi3/14', 'regex'); expect(result).toBe('Gi3\\/14'); diff --git a/public/app/features/templating/template_srv.ts b/public/app/features/templating/template_srv.ts index fc79d12ff9e..7ce539b6506 100644 --- a/public/app/features/templating/template_srv.ts +++ b/public/app/features/templating/template_srv.ts @@ -124,6 +124,13 @@ export class TemplateSrv { } return value; } + case 'urlescape': { + // like glob, but url escaped + if (_.isArray(value)) { + return escape('{' + value.join(',') + '}'); + } + return escape(value); + } default: { if (_.isArray(value)) { return '{' + value.join(',') + '}'; From 7da9c33ae4dae4232d242e8ab6710be720bdfd35 Mon Sep 17 00:00:00 2001 From: Benjamin Schweizer Date: Mon, 30 Jul 2018 17:28:50 +0200 Subject: [PATCH 02/32] fixed test result --- public/app/features/templating/specs/template_srv.jest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/features/templating/specs/template_srv.jest.ts b/public/app/features/templating/specs/template_srv.jest.ts index 040597888b6..85a159fc098 100644 --- a/public/app/features/templating/specs/template_srv.jest.ts +++ b/public/app/features/templating/specs/template_srv.jest.ts @@ -277,7 +277,7 @@ describe('templateSrv', function() { it('multi value and urlescape format should render url-escaped string', function() { var result = _templateSrv.formatValue(['foo()bar baz', 'test2'], 'urlescape'); - expect(result).toBe('foo%28%29bar%20baz%2Ctest2'); + expect(result).toBe('%7Bfoo%28%29bar%20baz%2Ctest2%7D'); }); it('slash should be properly escaped in regex format', function() { From 9220f83b3dcd4376d1ec8a5ab5bdf0a0e031a65f Mon Sep 17 00:00:00 2001 From: Benjamin Schweizer Date: Mon, 6 Aug 2018 21:54:12 +0200 Subject: [PATCH 03/32] replaced escape() call, renamed formatter to be more expressive --- docs/sources/reference/templating.md | 2 +- .../features/templating/specs/template_srv.jest.ts | 6 +++--- public/app/features/templating/template_srv.ts | 13 ++++++++++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/docs/sources/reference/templating.md b/docs/sources/reference/templating.md index d59117fefea..1482eb34350 100644 --- a/docs/sources/reference/templating.md +++ b/docs/sources/reference/templating.md @@ -52,7 +52,7 @@ Filter Option | Example | Raw | Interpolated | Description `csv`| ${servers:csv} | `'test1', 'test2'` | `test1,test2` | Formats multi-value variable as a comma-separated string `distributed`| ${servers:distributed} | `'test1', 'test2'` | `test1,servers=test2` | Formats multi-value variable in custom format for OpenTSDB. `lucene`| ${servers:lucene} | `'test', 'test2'` | `("test" OR "test2")` | Formats multi-value variable as a lucene expression. -`urlescape` | ${servers:urlescape} | `'foo()bar baz', 'test2'` | `{foo%28%29bar%20baz%2Ctest2}` | Formats multi-value variable into a glob, url escaped +`percentencode` | ${servers:percentencode} | `'foo()bar BAZ', 'test2'` | `{foo%28%29bar%20BAZ%2Ctest2}` | Formats multi-value variable into a glob, percent-escaped Test the formatting options on the [Grafana Play site](http://play.grafana.org/d/cJtIfcWiz/template-variable-formatting-options?orgId=1). diff --git a/public/app/features/templating/specs/template_srv.jest.ts b/public/app/features/templating/specs/template_srv.jest.ts index 85a159fc098..b4501e81f59 100644 --- a/public/app/features/templating/specs/template_srv.jest.ts +++ b/public/app/features/templating/specs/template_srv.jest.ts @@ -275,9 +275,9 @@ describe('templateSrv', function() { expect(result).toBe('test,test2'); }); - it('multi value and urlescape format should render url-escaped string', function() { - var result = _templateSrv.formatValue(['foo()bar baz', 'test2'], 'urlescape'); - expect(result).toBe('%7Bfoo%28%29bar%20baz%2Ctest2%7D'); + it('multi value and percentencode format should render percent-encoded string', function() { + var result = _templateSrv.formatValue(['foo()bar BAZ', 'test2'], 'percentencode'); + expect(result).toBe('%7Bfoo%28%29bar%20BAZ%2Ctest2%7D'); }); it('slash should be properly escaped in regex format', function() { diff --git a/public/app/features/templating/template_srv.ts b/public/app/features/templating/template_srv.ts index 7ce539b6506..3d462f1bcde 100644 --- a/public/app/features/templating/template_srv.ts +++ b/public/app/features/templating/template_srv.ts @@ -83,6 +83,13 @@ export class TemplateSrv { return '(' + quotedValues.join(' OR ') + ')'; } + // like encodeURIComponent() but for all characters except alpha-numerics + encodeURIQueryValue(str) { + return str.replace(/[^a-z0-9]/gi, function(c) { + return '%' + c.charCodeAt(0).toString(16); + }); + } + formatValue(value, format, variable) { // for some scopedVars there is no variable variable = variable || {}; @@ -124,12 +131,12 @@ export class TemplateSrv { } return value; } - case 'urlescape': { + case 'percentencode': { // like glob, but url escaped if (_.isArray(value)) { - return escape('{' + value.join(',') + '}'); + return this.encodeURIQueryValue('{' + value.join(',') + '}'); } - return escape(value); + return this.encodeURIQueryValue(value); } default: { if (_.isArray(value)) { From a653b277f312766ebfe0bb00ea0f6268139591d1 Mon Sep 17 00:00:00 2001 From: Benjamin Schweizer Date: Mon, 6 Aug 2018 22:04:33 +0200 Subject: [PATCH 04/32] switched to lowercase --- public/app/features/templating/specs/template_srv.jest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/features/templating/specs/template_srv.jest.ts b/public/app/features/templating/specs/template_srv.jest.ts index b4501e81f59..3d8b3af1ddd 100644 --- a/public/app/features/templating/specs/template_srv.jest.ts +++ b/public/app/features/templating/specs/template_srv.jest.ts @@ -277,7 +277,7 @@ describe('templateSrv', function() { it('multi value and percentencode format should render percent-encoded string', function() { var result = _templateSrv.formatValue(['foo()bar BAZ', 'test2'], 'percentencode'); - expect(result).toBe('%7Bfoo%28%29bar%20BAZ%2Ctest2%7D'); + expect(result).toBe('%7bfoo%28%29bar%20BAZ%2ctest2%7d'); }); it('slash should be properly escaped in regex format', function() { From f4b29b5782bea2efe8d428f9cc164678306cd7dd Mon Sep 17 00:00:00 2001 From: Benjamin Schweizer Date: Mon, 3 Sep 2018 16:08:52 +0200 Subject: [PATCH 05/32] fixed testcase --- public/app/features/templating/specs/template_srv.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/features/templating/specs/template_srv.test.ts b/public/app/features/templating/specs/template_srv.test.ts index 06c7ac552c9..3e5ddf8bf54 100644 --- a/public/app/features/templating/specs/template_srv.test.ts +++ b/public/app/features/templating/specs/template_srv.test.ts @@ -276,7 +276,7 @@ describe('templateSrv', function() { }); it('multi value and percentencode format should render percent-encoded string', function() { - var result = _templateSrv.formatValue(['foo()bar BAZ', 'test2'], 'percentencode'); + const result = _templateSrv.formatValue(['foo()bar BAZ', 'test2'], 'percentencode'); expect(result).toBe('%7bfoo%28%29bar%20BAZ%2ctest2%7d'); }); From 4712a87733ebf870950c932ef2802c4f2e15f9d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 18 Jan 2019 16:37:43 +0100 Subject: [PATCH 06/32] Revert "Specify expected encoding for access/secret key" --- docs/sources/http_api/data_source.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sources/http_api/data_source.md b/docs/sources/http_api/data_source.md index 9aaf29ec5f4..364b55b0cfc 100644 --- a/docs/sources/http_api/data_source.md +++ b/docs/sources/http_api/data_source.md @@ -188,8 +188,8 @@ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk "defaultRegion": "us-west-1" }, "secureJsonData": { - "accessKey": "Ol4pIDpeKSA6XikgOl4p", //should not be encoded - "secretKey": "dGVzdCBrZXkgYmxlYXNlIGRvbid0IHN0ZWFs" //should be Base-64 encoded + "accessKey": "Ol4pIDpeKSA6XikgOl4p", + "secretKey": "dGVzdCBrZXkgYmxlYXNlIGRvbid0IHN0ZWFs" } } ``` From 382a12c0fd2da62525c66a9a440a4c4fceafc4c7 Mon Sep 17 00:00:00 2001 From: Andrej Ocenas Date: Sat, 19 Jan 2019 16:58:26 +0100 Subject: [PATCH 07/32] Add loop counter for full refresh in playlist --- public/app/features/playlist/playlist_srv.ts | 22 ++-- .../playlist/specs/playlist_srv.test.ts | 103 ++++++++++++++++++ 2 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 public/app/features/playlist/specs/playlist_srv.test.ts diff --git a/public/app/features/playlist/playlist_srv.ts b/public/app/features/playlist/playlist_srv.ts index 9d3b635a1e5..0a80ce0cdf0 100644 --- a/public/app/features/playlist/playlist_srv.ts +++ b/public/app/features/playlist/playlist_srv.ts @@ -4,12 +4,13 @@ import appEvents from 'app/core/app_events'; import _ from 'lodash'; import { toUrlParams } from 'app/core/utils/url'; -class PlaylistSrv { +export class PlaylistSrv { private cancelPromise: any; - private dashboards: any; + private dashboards: Array<{ uri: string }>; private index: number; - private interval: any; + private interval: number; private startUrl: string; + private numberOfLoops = 0; isPlaying: boolean; /** @ngInject */ @@ -20,8 +21,15 @@ class PlaylistSrv { const playedAllDashboards = this.index > this.dashboards.length - 1; if (playedAllDashboards) { - window.location.href = this.startUrl; - return; + this.numberOfLoops++; + + // This does full reload of the playlist to keep memory in check due to existing leaks but at the same time + // we do not want page to flicker after each full loop. + if (this.numberOfLoops >= 3) { + window.location.href = this.startUrl; + return; + } + this.index = 0; } const dash = this.dashboards[this.index]; @@ -46,8 +54,8 @@ class PlaylistSrv { this.index = 0; this.isPlaying = true; - this.backendSrv.get(`/api/playlists/${playlistId}`).then(playlist => { - this.backendSrv.get(`/api/playlists/${playlistId}/dashboards`).then(dashboards => { + return this.backendSrv.get(`/api/playlists/${playlistId}`).then(playlist => { + return this.backendSrv.get(`/api/playlists/${playlistId}/dashboards`).then(dashboards => { this.dashboards = dashboards; this.interval = kbn.interval_to_ms(playlist.interval); this.next(); diff --git a/public/app/features/playlist/specs/playlist_srv.test.ts b/public/app/features/playlist/specs/playlist_srv.test.ts new file mode 100644 index 00000000000..e6b7671c964 --- /dev/null +++ b/public/app/features/playlist/specs/playlist_srv.test.ts @@ -0,0 +1,103 @@ +import { PlaylistSrv } from '../playlist_srv'; + +const dashboards = [{ uri: 'dash1' }, { uri: 'dash2' }]; + +const createPlaylistSrv = (): [PlaylistSrv, { url: jest.MockInstance }] => { + const mockBackendSrv = { + get: jest.fn(url => { + switch (url) { + case '/api/playlists/1': + return Promise.resolve({ interval: '1s' }); + case '/api/playlists/1/dashboards': + return Promise.resolve(dashboards); + default: + throw new Error(`Unexpected url=${url}`); + } + }), + }; + + const mockLocation = { + url: jest.fn(), + search: () => ({}), + }; + + const mockTimeout = jest.fn(); + (mockTimeout as any).cancel = jest.fn(); + + return [new PlaylistSrv(mockLocation, mockTimeout, mockBackendSrv), mockLocation]; +}; + +const mockWindowLocation = (): [jest.MockInstance, () => void] => { + const oldLocation = window.location; + const hrefMock = jest.fn(); + + // JSDom defines window in a way that you cannot tamper with location so this seems to be the only way to change it. + // https://github.com/facebook/jest/issues/5124#issuecomment-446659510 + delete window.location; + window.location = {} as any; + + // Only mocking href as that is all this test needs, but otherwise there is lots of things missing, so keep that + // in mind if this is reused. + Object.defineProperty(window.location, 'href', { + set: hrefMock, + get: hrefMock, + }); + const unmock = () => { + window.location = oldLocation; + }; + return [hrefMock, unmock]; +}; + +describe('PlaylistSrv', () => { + let srv: PlaylistSrv; + let mockLocationService: { url: jest.MockInstance }; + let hrefMock: jest.MockInstance; + let unmockLocation: () => void; + const initialUrl = 'http://localhost/playlist'; + + beforeEach(() => { + [srv, mockLocationService] = createPlaylistSrv(); + [hrefMock, unmockLocation] = mockWindowLocation(); + + // This will be cached in the srv when start() is called + hrefMock.mockReturnValue(initialUrl); + }); + + afterEach(() => { + unmockLocation(); + }); + + it('runs all dashboards in cycle and reloads page after 3 cycles', async () => { + await srv.start(1); + + for (let i = 0; i < 6; i++) { + expect(mockLocationService.url).toHaveBeenLastCalledWith(`dashboard/${dashboards[i % 2].uri}?`); + srv.next(); + } + + expect(hrefMock).toHaveBeenCalledTimes(2); + expect(hrefMock).toHaveBeenLastCalledWith(initialUrl); + }); + + it('keeps the refresh counter value after restarting', async () => { + await srv.start(1); + + // 1 complete loop + for (let i = 0; i < 3; i++) { + expect(mockLocationService.url).toHaveBeenLastCalledWith(`dashboard/${dashboards[i % 2].uri}?`); + srv.next(); + } + + srv.stop(); + await srv.start(1); + + // Another 2 loops + for (let i = 0; i < 4; i++) { + expect(mockLocationService.url).toHaveBeenLastCalledWith(`dashboard/${dashboards[i % 2].uri}?`); + srv.next(); + } + + expect(hrefMock).toHaveBeenCalledTimes(3); + expect(hrefMock).toHaveBeenLastCalledWith(initialUrl); + }); +}); From 151b838f0ba4e4f66f321fd74d65b2a06566d4a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Tue, 22 Jan 2019 13:07:03 +0100 Subject: [PATCH 08/32] fixes:#14282 - Do not change folder for persisted dashboards --- .../features/dashboard/folder_picker/folder_picker.ts | 11 ++++++++++- public/app/features/dashboard/save_as_modal.ts | 3 ++- public/app/features/dashboard/settings/settings.html | 3 ++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/public/app/features/dashboard/folder_picker/folder_picker.ts b/public/app/features/dashboard/folder_picker/folder_picker.ts index 80651fecb7e..11fab840278 100644 --- a/public/app/features/dashboard/folder_picker/folder_picker.ts +++ b/public/app/features/dashboard/folder_picker/folder_picker.ts @@ -21,6 +21,7 @@ export class FolderPickerCtrl { hasValidationError: boolean; validationError: any; isEditor: boolean; + dashboardId?: number; /** @ngInject */ constructor(private backendSrv, private validationSrv, private contextSrv) { @@ -131,6 +132,7 @@ export class FolderPickerCtrl { private loadInitialValue() { const resetFolder = { text: this.initialTitle, value: null }; const rootFolder = { text: this.rootName, value: 0 }; + const emptyFolder = { text: '', value: null }; this.getOptions('').then(result => { let folder; @@ -144,7 +146,13 @@ export class FolderPickerCtrl { if (this.isEditor) { folder = rootFolder; } else { - folder = result.length > 0 ? result[0] : resetFolder; + // We shouldn't assign a random folder without the user actively choosing it on a persisted dashboard + const isPersistedDashBoard = this.dashboardId ? true : false; + if (isPersistedDashBoard) { + folder = emptyFolder; + } else { + folder = result.length > 0 ? result[0] : resetFolder; + } } } @@ -176,6 +184,7 @@ export function folderPicker() { exitFolderCreation: '&', enableCreateNew: '@', enableReset: '@', + dashboardId: ' + label-class="width-7" + dashboard-id="ctrl.clone.id"> diff --git a/public/app/features/dashboard/settings/settings.html b/public/app/features/dashboard/settings/settings.html index 46d84a7a2fd..97002f7bf92 100644 --- a/public/app/features/dashboard/settings/settings.html +++ b/public/app/features/dashboard/settings/settings.html @@ -51,7 +51,8 @@ on-change="ctrl.onFolderChange($folder)" enable-create-new="true" is-valid-selection="true" - label-class="width-7"> + label-class="width-7" + dashboard-id="ctrl.dashboard.id"> From 85838a40d6e415ff79b7d6f60fb5b6d34a780eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Tue, 22 Jan 2019 13:59:58 +0100 Subject: [PATCH 09/32] fix: Dispatch the correct action (#14985) --- public/app/features/explore/TableContainer.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/app/features/explore/TableContainer.tsx b/public/app/features/explore/TableContainer.tsx index 1d00a441e14..ed26ce5147f 100644 --- a/public/app/features/explore/TableContainer.tsx +++ b/public/app/features/explore/TableContainer.tsx @@ -5,7 +5,7 @@ import { connect } from 'react-redux'; import { ExploreId, ExploreItemState } from 'app/types/explore'; import { StoreState } from 'app/types'; -import { toggleGraph } from './state/actions'; +import { toggleTable } from './state/actions'; import Table from './Table'; import Panel from './Panel'; import TableModel from 'app/core/table_model'; @@ -16,12 +16,12 @@ interface TableContainerProps { onClickCell: (key: string, value: string) => void; showingTable: boolean; tableResult?: TableModel; - toggleGraph: typeof toggleGraph; + toggleTable: typeof toggleTable; } export class TableContainer extends PureComponent { onClickTableButton = () => { - this.props.toggleGraph(this.props.exploreId); + this.props.toggleTable(this.props.exploreId); }; render() { @@ -43,7 +43,7 @@ function mapStateToProps(state: StoreState, { exploreId }) { } const mapDispatchToProps = { - toggleGraph, + toggleTable, }; export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(TableContainer)); From bde4b76c167c0b45e1f77b75a8270afce0da5a6a Mon Sep 17 00:00:00 2001 From: Benjamin Schweizer Date: Tue, 22 Jan 2019 15:09:58 +0100 Subject: [PATCH 10/32] based on encodeURIComponent() using strict RFC 3986 sub-delims --- docs/sources/reference/templating.md | 2 +- .../features/templating/specs/template_srv.test.ts | 2 +- public/app/features/templating/template_srv.ts | 14 ++++++++------ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/sources/reference/templating.md b/docs/sources/reference/templating.md index 900288d15a7..3ef32b1b10f 100644 --- a/docs/sources/reference/templating.md +++ b/docs/sources/reference/templating.md @@ -52,7 +52,7 @@ Filter Option | Example | Raw | Interpolated | Description `csv`| ${servers:csv} | `'test1', 'test2'` | `test1,test2` | Formats multi-value variable as a comma-separated string `distributed`| ${servers:distributed} | `'test1', 'test2'` | `test1,servers=test2` | Formats multi-value variable in custom format for OpenTSDB. `lucene`| ${servers:lucene} | `'test', 'test2'` | `("test" OR "test2")` | Formats multi-value variable as a lucene expression. -`percentencode` | ${servers:percentencode} | `'foo()bar BAZ', 'test2'` | `{foo%28%29bar%20BAZ%2Ctest2}` | Formats multi-value variable into a glob, percent-escaped +`percentencode` | ${servers:percentencode} | `'foo()bar BAZ', 'test2'` | `{foo%28%29bar%20BAZ%2Ctest2}` | Formats multi-value variable into a glob, percent-encoded. Test the formatting options on the [Grafana Play site](http://play.grafana.org/d/cJtIfcWiz/template-variable-formatting-options?orgId=1). diff --git a/public/app/features/templating/specs/template_srv.test.ts b/public/app/features/templating/specs/template_srv.test.ts index 8d6bf5ed668..4288b5f3928 100644 --- a/public/app/features/templating/specs/template_srv.test.ts +++ b/public/app/features/templating/specs/template_srv.test.ts @@ -277,7 +277,7 @@ describe('templateSrv', () => { it('multi value and percentencode format should render percent-encoded string', () => { const result = _templateSrv.formatValue(['foo()bar BAZ', 'test2'], 'percentencode'); - expect(result).toBe('%7bfoo%28%29bar%20BAZ%2ctest2%7d'); + expect(result).toBe('%7Bfoo%28%29bar%20BAZ%2Ctest2%7D'); }); it('slash should be properly escaped in regex format', () => { diff --git a/public/app/features/templating/template_srv.ts b/public/app/features/templating/template_srv.ts index a969b058d7e..07656924c9c 100644 --- a/public/app/features/templating/template_srv.ts +++ b/public/app/features/templating/template_srv.ts @@ -77,10 +77,12 @@ export class TemplateSrv { return '(' + quotedValues.join(' OR ') + ')'; } - // like encodeURIComponent() but for all characters except alpha-numerics - encodeURIQueryValue(str) { - return str.replace(/[^a-z0-9]/gi, function(c) { - return '%' + c.charCodeAt(0).toString(16); + // encode string according to RFC 3986; in contrast to encodeURIComponent() + // also the sub-delims "!", "'", "(", ")" and "*" are encoded; + // unicode handling uses UTF-8 as in ECMA-262. + encodeURIComponentStrict(str) { + return encodeURIComponent(str).replace(/[!'()*]/g, (c) => { + return '%' + c.charCodeAt(0).toString(16).toUpperCase(); }); } @@ -128,9 +130,9 @@ export class TemplateSrv { case 'percentencode': { // like glob, but url escaped if (_.isArray(value)) { - return this.encodeURIQueryValue('{' + value.join(',') + '}'); + return this.encodeURIComponentStrict('{' + value.join(',') + '}'); } - return this.encodeURIQueryValue(value); + return this.encodeURIComponentStrict(value); } default: { if (_.isArray(value)) { From 0151846e1e0c624f2490dcf0bfbead5d0a8e9218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 22 Jan 2019 17:23:24 +0100 Subject: [PATCH 11/32] Updated home dashboard, removed home dashboard header --- pkg/api/dashboard.go | 2 +- public/dashboards/home.json | 21 ++------------------- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index 2789b0bf51e..5959c230fb9 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -336,7 +336,7 @@ func addGettingStartedPanelToHomeDashboard(dash *simplejson.Json) { "id": 123123, "gridPos": map[string]interface{}{ "x": 0, - "y": 3, + "y": 0, "w": 24, "h": 4, }, diff --git a/public/dashboards/home.json b/public/dashboards/home.json index f2c441053bb..17795d64aa3 100644 --- a/public/dashboards/home.json +++ b/public/dashboards/home.json @@ -10,23 +10,6 @@ "id": null, "links": [], "panels": [ - { - "content": "
\n Home Dashboard\n
", - "editable": true, - "id": 1, - "links": [], - "mode": "html", - "style": {}, - "title": "", - "transparent": true, - "type": "text", - "gridPos": { - "w": 24, - "h": 3, - "x": 0, - "y": 0 - } - }, { "folderId": 0, "headings": true, @@ -45,7 +28,7 @@ "w": 12, "h": 17, "x": 0, - "y": 6 + "y": 1 } }, { @@ -60,7 +43,7 @@ "w": 12, "h": 17, "x": 12, - "y": 6 + "y": 1 } } ], From 2a507770019ce103d1dc4cdeafa2def8c0b92135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 22 Jan 2019 17:41:36 +0100 Subject: [PATCH 12/32] use resetfolder instead so it shows current folder --- public/app/features/dashboard/folder_picker/folder_picker.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/public/app/features/dashboard/folder_picker/folder_picker.ts b/public/app/features/dashboard/folder_picker/folder_picker.ts index 11fab840278..0896b3c793c 100644 --- a/public/app/features/dashboard/folder_picker/folder_picker.ts +++ b/public/app/features/dashboard/folder_picker/folder_picker.ts @@ -132,7 +132,6 @@ export class FolderPickerCtrl { private loadInitialValue() { const resetFolder = { text: this.initialTitle, value: null }; const rootFolder = { text: this.rootName, value: 0 }; - const emptyFolder = { text: '', value: null }; this.getOptions('').then(result => { let folder; @@ -149,7 +148,7 @@ export class FolderPickerCtrl { // We shouldn't assign a random folder without the user actively choosing it on a persisted dashboard const isPersistedDashBoard = this.dashboardId ? true : false; if (isPersistedDashBoard) { - folder = emptyFolder; + folder = resetFolder; } else { folder = result.length > 0 ? result[0] : resetFolder; } From 3a390a994b4337797c80cdd6d9fa0cf8ea1c972a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 22 Jan 2019 17:46:38 +0100 Subject: [PATCH 13/32] Update ROADMAP.md --- ROADMAP.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 891bc9f790b..b5e62578475 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -5,18 +5,22 @@ But it will give you an idea of our current vision and plan. ### Short term (1-2 months) - PRs & Bugs - - Multi-Stat panel + - React Panel Support + - React Query Editor Support - Metrics & Log Explore UI - + - Grafana UI library shared between grafana & plugins + - Seperate visualization from panels + - More reuse between Explore & dashboard + - Explore logging support for more data sources + ### Mid term (2-4 months) - - React Panels - - Change visualization (panel type) on the fly. - - Templating Query Editor UI Plugin hook - - Backend plugins + - Drilldown links + - Dashboards as code workflows + - React migration + - New panels ### Long term (4 - 8 months) - Alerting improvements (silence, per series tracking, etc) - - Progress on React migration ### In a distant future far far away - Meta queries From 2bdc92f7ddf9164fabf3df7eda79c22694cee2cc Mon Sep 17 00:00:00 2001 From: Julien Pivotto Date: Tue, 22 Jan 2019 20:42:56 +0100 Subject: [PATCH 14/32] Fix a typo in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f5fed293d5..5a691465626 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ * **Auth**: Prevent password reset when login form is disabled or either LDAP or Auth Proxy is enabled [#14246](https://github.com/grafana/grafana/issues/14246), thx [@SilverFire](https://github.com/SilverFire) * **Dataproxy**: Override incoming Authorization header [#13815](https://github.com/grafana/grafana/issues/13815), thx [@kornholi](https://github.com/kornholi) * **Admin**: Fix prevent removing last grafana admin permissions [#11067](https://github.com/grafana/grafana/issues/11067), thx [@danielbh](https://github.com/danielbh) -* **Templating**: Escaping "Custom" template variables [#13754](https://github.com/grafana/grafana/issues/13754), thx [@IntegersOfK]req(https://github.com/IntegersOfK) +* **Templating**: Escaping "Custom" template variables [#13754](https://github.com/grafana/grafana/issues/13754), thx [@IntegersOfK](https://github.com/IntegersOfK) * **Admin**: When multiple user invitations, all links are the same as the first user who was invited [#14483](https://github.com/grafana/grafana/issues/14483) * **LDAP**: Upgrade go-ldap to v3 [#14548](https://github.com/grafana/grafana/issues/14548) * **Proxy whitelist**: Add CIDR capability to auth_proxy whitelist [#14546](https://github.com/grafana/grafana/issues/14546), thx [@jacobrichard](https://github.com/jacobrichard) From 26385dea8f1101b579bc21e756c7d54a8f8f369e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 22 Jan 2019 21:36:36 +0100 Subject: [PATCH 15/32] Began work on improving structure and organization of components under features/dashboard, #14062 --- public/app/features/dashboard/all.ts | 19 ++++---------- .../DashExportModal/DashExportCtrl.ts} | 4 +-- .../DashboardExporter.test.ts} | 4 +-- .../DashExportModal/DashboardExporter.ts} | 2 +- .../components/DashExportModal/index.ts | 2 ++ .../DashExportModal/template.html} | 0 .../DashLinks/DashLinksContainerCtrl.ts} | 2 +- .../DashLinks/DashLinksEditorCtrl.ts} | 6 ++--- .../DashLinks}/editor.html | 0 .../dashboard/components/DashLinks/index.ts | 2 ++ .../DashNav/DashNavCtrl.ts} | 4 +-- .../dashboard/components/DashNav/index.ts | 1 + .../DashNav/template.html} | 0 .../ExportDataModal/ExportDataModalCtrl.ts} | 2 +- .../components/ExportDataModal/index.ts | 1 + .../ExportDataModal/template.html} | 0 .../FolderPicker/FolderPickerCtrl.ts} | 2 +- .../components/FolderPicker/index.ts | 1 + .../FolderPicker/template.html} | 0 .../dashboard/folder_permissions_ctrl.ts | 25 ------------------- .../CreateFolderCtrl.ts} | 0 .../DashboardImportCtrl.test.ts} | 4 +-- .../DashboardImportCtrl.ts} | 0 .../FolderDashboardsCtrl.ts} | 2 +- .../MoveToFolderModal/MoveToFolderCtrl.ts} | 2 +- .../components/MoveToFolderModal/index.ts | 1 + .../MoveToFolderModal/template.html} | 0 .../app/features/manage-dashboards/index.ts | 10 +++++++- .../services/FolderPageLoader.ts} | 0 29 files changed, 39 insertions(+), 57 deletions(-) rename public/app/features/dashboard/{export/export_modal.ts => components/DashExportModal/DashExportCtrl.ts} (92%) rename public/app/features/dashboard/{specs/exporter.test.ts => components/DashExportModal/DashboardExporter.test.ts} (98%) rename public/app/features/dashboard/{export/exporter.ts => components/DashExportModal/DashboardExporter.ts} (98%) create mode 100644 public/app/features/dashboard/components/DashExportModal/index.ts rename public/app/features/dashboard/{export/export_modal.html => components/DashExportModal/template.html} (100%) rename public/app/features/dashboard/{dashlinks/module.ts => components/DashLinks/DashLinksContainerCtrl.ts} (99%) rename public/app/features/dashboard/{dashlinks/editor.ts => components/DashLinks/DashLinksEditorCtrl.ts} (90%) rename public/app/features/dashboard/{dashlinks => components/DashLinks}/editor.html (100%) create mode 100644 public/app/features/dashboard/components/DashLinks/index.ts rename public/app/features/dashboard/{dashnav/dashnav.ts => components/DashNav/DashNavCtrl.ts} (95%) create mode 100644 public/app/features/dashboard/components/DashNav/index.ts rename public/app/features/dashboard/{dashnav/dashnav.html => components/DashNav/template.html} (100%) rename public/app/features/dashboard/{export_data/export_data_modal.ts => components/ExportDataModal/ExportDataModalCtrl.ts} (92%) create mode 100644 public/app/features/dashboard/components/ExportDataModal/index.ts rename public/app/features/dashboard/{export_data/export_data_modal.html => components/ExportDataModal/template.html} (100%) rename public/app/features/dashboard/{folder_picker/folder_picker.ts => components/FolderPicker/FolderPickerCtrl.ts} (98%) create mode 100644 public/app/features/dashboard/components/FolderPicker/index.ts rename public/app/features/dashboard/{folder_picker/folder_picker.html => components/FolderPicker/template.html} (100%) delete mode 100644 public/app/features/dashboard/folder_permissions_ctrl.ts rename public/app/features/{dashboard/create_folder_ctrl.ts => manage-dashboards/CreateFolderCtrl.ts} (100%) rename public/app/features/{dashboard/specs/dashboard_import_ctrl.test.ts => manage-dashboards/DashboardImportCtrl.test.ts} (95%) rename public/app/features/{dashboard/dashboard_import_ctrl.ts => manage-dashboards/DashboardImportCtrl.ts} (100%) rename public/app/features/{dashboard/folder_dashboards_ctrl.ts => manage-dashboards/FolderDashboardsCtrl.ts} (90%) rename public/app/features/{dashboard/move_to_folder_modal/move_to_folder.ts => manage-dashboards/components/MoveToFolderModal/MoveToFolderCtrl.ts} (93%) create mode 100644 public/app/features/manage-dashboards/components/MoveToFolderModal/index.ts rename public/app/features/{dashboard/move_to_folder_modal/move_to_folder.html => manage-dashboards/components/MoveToFolderModal/template.html} (100%) rename public/app/features/{dashboard/folder_page_loader.ts => manage-dashboards/services/FolderPageLoader.ts} (100%) diff --git a/public/app/features/dashboard/all.ts b/public/app/features/dashboard/all.ts index 5ec4e5e3929..01570ae4744 100644 --- a/public/app/features/dashboard/all.ts +++ b/public/app/features/dashboard/all.ts @@ -2,7 +2,6 @@ import './dashboard_ctrl'; import './alerting_srv'; import './history/history'; import './dashboard_loader_srv'; -import './dashnav/dashnav'; import './submenu/submenu'; import './save_as_modal'; import './save_modal'; @@ -17,17 +16,17 @@ import './unsaved_changes_srv'; import './unsaved_changes_modal'; import './timepicker/timepicker'; import './upload'; -import './export/export_modal'; -import './export_data/export_data_modal'; import './ad_hoc_filters'; import './repeat_option/repeat_option'; import './dashgrid/DashboardGridDirective'; import './dashgrid/RowOptions'; -import './folder_picker/folder_picker'; -import './move_to_folder_modal/move_to_folder'; import './settings/settings'; import './panellinks/module'; -import './dashlinks/module'; +import './components/DashLinks'; +import './components/DashExportModal'; +import './components/DashNav'; +import './components/ExportDataModal'; +import './components/FolderPicker'; // angular wrappers import { react2AngularDirective } from 'app/core/utils/react2angular'; @@ -35,11 +34,3 @@ import DashboardPermissions from './permissions/DashboardPermissions'; react2AngularDirective('dashboardPermissions', DashboardPermissions, ['dashboardId', 'folder']); -import coreModule from 'app/core/core_module'; -import { FolderDashboardsCtrl } from './folder_dashboards_ctrl'; -import { DashboardImportCtrl } from './dashboard_import_ctrl'; -import { CreateFolderCtrl } from './create_folder_ctrl'; - -coreModule.controller('FolderDashboardsCtrl', FolderDashboardsCtrl); -coreModule.controller('DashboardImportCtrl', DashboardImportCtrl); -coreModule.controller('CreateFolderCtrl', CreateFolderCtrl); diff --git a/public/app/features/dashboard/export/export_modal.ts b/public/app/features/dashboard/components/DashExportModal/DashExportCtrl.ts similarity index 92% rename from public/app/features/dashboard/export/export_modal.ts rename to public/app/features/dashboard/components/DashExportModal/DashExportCtrl.ts index 8136c77cd8f..7769bdf114a 100644 --- a/public/app/features/dashboard/export/export_modal.ts +++ b/public/app/features/dashboard/components/DashExportModal/DashExportCtrl.ts @@ -2,7 +2,7 @@ import angular from 'angular'; import { saveAs } from 'file-saver'; import coreModule from 'app/core/core_module'; -import { DashboardExporter } from './exporter'; +import { DashboardExporter } from './DashboardExporter'; export class DashExportCtrl { dash: any; @@ -66,7 +66,7 @@ export class DashExportCtrl { export function dashExportDirective() { return { restrict: 'E', - templateUrl: 'public/app/features/dashboard/export/export_modal.html', + templateUrl: 'public/app/features/dashboard/components/DashExportModal/template.html', controller: DashExportCtrl, bindToController: true, controllerAs: 'ctrl', diff --git a/public/app/features/dashboard/specs/exporter.test.ts b/public/app/features/dashboard/components/DashExportModal/DashboardExporter.test.ts similarity index 98% rename from public/app/features/dashboard/specs/exporter.test.ts rename to public/app/features/dashboard/components/DashExportModal/DashboardExporter.test.ts index eac6b0b272a..20ab21541a5 100644 --- a/public/app/features/dashboard/specs/exporter.test.ts +++ b/public/app/features/dashboard/components/DashExportModal/DashboardExporter.test.ts @@ -6,8 +6,8 @@ jest.mock('app/core/store', () => { import _ from 'lodash'; import config from 'app/core/config'; -import { DashboardExporter } from '../export/exporter'; -import { DashboardModel } from '../dashboard_model'; +import { DashboardExporter } from './DashboardExporter'; +import { DashboardModel } from '../../dashboard_model'; describe('given dashboard with repeated panels', () => { let dash, exported; diff --git a/public/app/features/dashboard/export/exporter.ts b/public/app/features/dashboard/components/DashExportModal/DashboardExporter.ts similarity index 98% rename from public/app/features/dashboard/export/exporter.ts rename to public/app/features/dashboard/components/DashExportModal/DashboardExporter.ts index 7aecb5c384f..22b93b767d6 100644 --- a/public/app/features/dashboard/export/exporter.ts +++ b/public/app/features/dashboard/components/DashExportModal/DashboardExporter.ts @@ -1,6 +1,6 @@ import config from 'app/core/config'; import _ from 'lodash'; -import { DashboardModel } from '../dashboard_model'; +import { DashboardModel } from '../../dashboard_model'; export class DashboardExporter { constructor(private datasourceSrv) {} diff --git a/public/app/features/dashboard/components/DashExportModal/index.ts b/public/app/features/dashboard/components/DashExportModal/index.ts new file mode 100644 index 00000000000..6529cf07ad9 --- /dev/null +++ b/public/app/features/dashboard/components/DashExportModal/index.ts @@ -0,0 +1,2 @@ +export { DashboardExporter } from './DashboardExporter'; +export { DashExportCtrl } from './DashExportCtrl'; diff --git a/public/app/features/dashboard/export/export_modal.html b/public/app/features/dashboard/components/DashExportModal/template.html similarity index 100% rename from public/app/features/dashboard/export/export_modal.html rename to public/app/features/dashboard/components/DashExportModal/template.html diff --git a/public/app/features/dashboard/dashlinks/module.ts b/public/app/features/dashboard/components/DashLinks/DashLinksContainerCtrl.ts similarity index 99% rename from public/app/features/dashboard/dashlinks/module.ts rename to public/app/features/dashboard/components/DashLinks/DashLinksContainerCtrl.ts index c951538d45d..a08e438a46c 100644 --- a/public/app/features/dashboard/dashlinks/module.ts +++ b/public/app/features/dashboard/components/DashLinks/DashLinksContainerCtrl.ts @@ -1,6 +1,6 @@ import angular from 'angular'; import _ from 'lodash'; -import { iconMap } from './editor'; +import { iconMap } from './DashLinksEditorCtrl'; function dashLinksContainer() { return { diff --git a/public/app/features/dashboard/dashlinks/editor.ts b/public/app/features/dashboard/components/DashLinks/DashLinksEditorCtrl.ts similarity index 90% rename from public/app/features/dashboard/dashlinks/editor.ts rename to public/app/features/dashboard/components/DashLinks/DashLinksEditorCtrl.ts index 482052469db..398ad757bf3 100644 --- a/public/app/features/dashboard/dashlinks/editor.ts +++ b/public/app/features/dashboard/components/DashLinks/DashLinksEditorCtrl.ts @@ -11,7 +11,7 @@ export let iconMap = { cloud: 'fa-cloud', }; -export class DashLinkEditorCtrl { +export class DashLinksEditorCtrl { dashboard: any; iconMap: any; mode: any; @@ -65,8 +65,8 @@ export class DashLinkEditorCtrl { function dashLinksEditor() { return { restrict: 'E', - controller: DashLinkEditorCtrl, - templateUrl: 'public/app/features/dashboard/dashlinks/editor.html', + controller: DashLinksEditorCtrl, + templateUrl: 'public/app/features/dashboard/components/DashLinks/editor.html', bindToController: true, controllerAs: 'ctrl', scope: { diff --git a/public/app/features/dashboard/dashlinks/editor.html b/public/app/features/dashboard/components/DashLinks/editor.html similarity index 100% rename from public/app/features/dashboard/dashlinks/editor.html rename to public/app/features/dashboard/components/DashLinks/editor.html diff --git a/public/app/features/dashboard/components/DashLinks/index.ts b/public/app/features/dashboard/components/DashLinks/index.ts new file mode 100644 index 00000000000..ef118d4a84c --- /dev/null +++ b/public/app/features/dashboard/components/DashLinks/index.ts @@ -0,0 +1,2 @@ +export { DashLinksContainerCtrl } from './DashLinksContainerCtrl'; +export { DashLinksEditorCtrl } from './DashLinksEditorCtrl'; diff --git a/public/app/features/dashboard/dashnav/dashnav.ts b/public/app/features/dashboard/components/DashNav/DashNavCtrl.ts similarity index 95% rename from public/app/features/dashboard/dashnav/dashnav.ts rename to public/app/features/dashboard/components/DashNav/DashNavCtrl.ts index 1c83b2d0bdb..0f28bb0afdb 100644 --- a/public/app/features/dashboard/dashnav/dashnav.ts +++ b/public/app/features/dashboard/components/DashNav/DashNavCtrl.ts @@ -1,7 +1,7 @@ import moment from 'moment'; import angular from 'angular'; import { appEvents, NavModel } from 'app/core/core'; -import { DashboardModel } from '../dashboard_model'; +import { DashboardModel } from '../../dashboard_model'; export class DashNavCtrl { dashboard: DashboardModel; @@ -107,7 +107,7 @@ export class DashNavCtrl { export function dashNavDirective() { return { restrict: 'E', - templateUrl: 'public/app/features/dashboard/dashnav/dashnav.html', + templateUrl: 'public/app/features/dashboard/components/DashNav/template.html', controller: DashNavCtrl, bindToController: true, controllerAs: 'ctrl', diff --git a/public/app/features/dashboard/components/DashNav/index.ts b/public/app/features/dashboard/components/DashNav/index.ts new file mode 100644 index 00000000000..854e32b24d2 --- /dev/null +++ b/public/app/features/dashboard/components/DashNav/index.ts @@ -0,0 +1 @@ +export { DashNavCtrl } from './DashNavCtrl'; diff --git a/public/app/features/dashboard/dashnav/dashnav.html b/public/app/features/dashboard/components/DashNav/template.html similarity index 100% rename from public/app/features/dashboard/dashnav/dashnav.html rename to public/app/features/dashboard/components/DashNav/template.html diff --git a/public/app/features/dashboard/export_data/export_data_modal.ts b/public/app/features/dashboard/components/ExportDataModal/ExportDataModalCtrl.ts similarity index 92% rename from public/app/features/dashboard/export_data/export_data_modal.ts rename to public/app/features/dashboard/components/ExportDataModal/ExportDataModalCtrl.ts index 460f80079d9..f87daa94ee7 100644 --- a/public/app/features/dashboard/export_data/export_data_modal.ts +++ b/public/app/features/dashboard/components/ExportDataModal/ExportDataModalCtrl.ts @@ -31,7 +31,7 @@ export class ExportDataModalCtrl { export function exportDataModal() { return { restrict: 'E', - templateUrl: 'public/app/features/dashboard/export_data/export_data_modal.html', + templateUrl: 'public/app/features/dashboard/components/ExportDataModal/template.html', controller: ExportDataModalCtrl, controllerAs: 'ctrl', scope: { diff --git a/public/app/features/dashboard/components/ExportDataModal/index.ts b/public/app/features/dashboard/components/ExportDataModal/index.ts new file mode 100644 index 00000000000..6df4fd00434 --- /dev/null +++ b/public/app/features/dashboard/components/ExportDataModal/index.ts @@ -0,0 +1 @@ +export { ExportDataModalCtrl } from './ExportDataModalCtrl'; diff --git a/public/app/features/dashboard/export_data/export_data_modal.html b/public/app/features/dashboard/components/ExportDataModal/template.html similarity index 100% rename from public/app/features/dashboard/export_data/export_data_modal.html rename to public/app/features/dashboard/components/ExportDataModal/template.html diff --git a/public/app/features/dashboard/folder_picker/folder_picker.ts b/public/app/features/dashboard/components/FolderPicker/FolderPickerCtrl.ts similarity index 98% rename from public/app/features/dashboard/folder_picker/folder_picker.ts rename to public/app/features/dashboard/components/FolderPicker/FolderPickerCtrl.ts index 0896b3c793c..93d43d36038 100644 --- a/public/app/features/dashboard/folder_picker/folder_picker.ts +++ b/public/app/features/dashboard/components/FolderPicker/FolderPickerCtrl.ts @@ -168,7 +168,7 @@ export class FolderPickerCtrl { export function folderPicker() { return { restrict: 'E', - templateUrl: 'public/app/features/dashboard/folder_picker/folder_picker.html', + templateUrl: 'public/app/features/dashboard/components/FolderPicker/template.html', controller: FolderPickerCtrl, bindToController: true, controllerAs: 'ctrl', diff --git a/public/app/features/dashboard/components/FolderPicker/index.ts b/public/app/features/dashboard/components/FolderPicker/index.ts new file mode 100644 index 00000000000..7550f7fd573 --- /dev/null +++ b/public/app/features/dashboard/components/FolderPicker/index.ts @@ -0,0 +1 @@ +export { FolderPickerCtrl } from './FolderPickerCtrl'; diff --git a/public/app/features/dashboard/folder_picker/folder_picker.html b/public/app/features/dashboard/components/FolderPicker/template.html similarity index 100% rename from public/app/features/dashboard/folder_picker/folder_picker.html rename to public/app/features/dashboard/components/FolderPicker/template.html diff --git a/public/app/features/dashboard/folder_permissions_ctrl.ts b/public/app/features/dashboard/folder_permissions_ctrl.ts deleted file mode 100644 index 4ab91acb3d9..00000000000 --- a/public/app/features/dashboard/folder_permissions_ctrl.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { FolderPageLoader } from './folder_page_loader'; - -export class FolderPermissionsCtrl { - navModel: any; - folderId: number; - uid: string; - dashboard: any; - meta: any; - - /** @ngInject */ - constructor(private backendSrv, navModelSrv, private $routeParams, $location) { - if (this.$routeParams.uid) { - this.uid = $routeParams.uid; - - new FolderPageLoader(this.backendSrv).load(this, this.uid, 'manage-folder-permissions').then(folder => { - if ($location.path() !== folder.meta.url) { - $location.path(`${folder.meta.url}/permissions`).replace(); - } - - this.dashboard = folder.dashboard; - this.meta = folder.meta; - }); - } - } -} diff --git a/public/app/features/dashboard/create_folder_ctrl.ts b/public/app/features/manage-dashboards/CreateFolderCtrl.ts similarity index 100% rename from public/app/features/dashboard/create_folder_ctrl.ts rename to public/app/features/manage-dashboards/CreateFolderCtrl.ts diff --git a/public/app/features/dashboard/specs/dashboard_import_ctrl.test.ts b/public/app/features/manage-dashboards/DashboardImportCtrl.test.ts similarity index 95% rename from public/app/features/dashboard/specs/dashboard_import_ctrl.test.ts rename to public/app/features/manage-dashboards/DashboardImportCtrl.test.ts index bcde009cb3a..c9037c0a62d 100644 --- a/public/app/features/dashboard/specs/dashboard_import_ctrl.test.ts +++ b/public/app/features/manage-dashboards/DashboardImportCtrl.test.ts @@ -1,5 +1,5 @@ -import { DashboardImportCtrl } from '../dashboard_import_ctrl'; -import config from '../../../core/config'; +import { DashboardImportCtrl } from './DashboardImportCtrl'; +import config from 'app/core/config'; describe('DashboardImportCtrl', () => { const ctx: any = {}; diff --git a/public/app/features/dashboard/dashboard_import_ctrl.ts b/public/app/features/manage-dashboards/DashboardImportCtrl.ts similarity index 100% rename from public/app/features/dashboard/dashboard_import_ctrl.ts rename to public/app/features/manage-dashboards/DashboardImportCtrl.ts diff --git a/public/app/features/dashboard/folder_dashboards_ctrl.ts b/public/app/features/manage-dashboards/FolderDashboardsCtrl.ts similarity index 90% rename from public/app/features/dashboard/folder_dashboards_ctrl.ts rename to public/app/features/manage-dashboards/FolderDashboardsCtrl.ts index 05cc420c489..6241472432c 100644 --- a/public/app/features/dashboard/folder_dashboards_ctrl.ts +++ b/public/app/features/manage-dashboards/FolderDashboardsCtrl.ts @@ -1,4 +1,4 @@ -import { FolderPageLoader } from './folder_page_loader'; +import { FolderPageLoader } from './services/FolderPageLoader'; import locationUtil from 'app/core/utils/location_util'; export class FolderDashboardsCtrl { diff --git a/public/app/features/dashboard/move_to_folder_modal/move_to_folder.ts b/public/app/features/manage-dashboards/components/MoveToFolderModal/MoveToFolderCtrl.ts similarity index 93% rename from public/app/features/dashboard/move_to_folder_modal/move_to_folder.ts rename to public/app/features/manage-dashboards/components/MoveToFolderModal/MoveToFolderCtrl.ts index 075583b971b..c183f38d92a 100644 --- a/public/app/features/dashboard/move_to_folder_modal/move_to_folder.ts +++ b/public/app/features/manage-dashboards/components/MoveToFolderModal/MoveToFolderCtrl.ts @@ -46,7 +46,7 @@ export class MoveToFolderCtrl { export function moveToFolderModal() { return { restrict: 'E', - templateUrl: 'public/app/features/dashboard/move_to_folder_modal/move_to_folder.html', + templateUrl: 'public/app/features/manage-dashboards/components/MoveToFolderModal/template.html', controller: MoveToFolderCtrl, bindToController: true, controllerAs: 'ctrl', diff --git a/public/app/features/manage-dashboards/components/MoveToFolderModal/index.ts b/public/app/features/manage-dashboards/components/MoveToFolderModal/index.ts new file mode 100644 index 00000000000..df0553aedb9 --- /dev/null +++ b/public/app/features/manage-dashboards/components/MoveToFolderModal/index.ts @@ -0,0 +1 @@ +export { MoveToFolderCtrl } from './MoveToFolderCtrl'; diff --git a/public/app/features/dashboard/move_to_folder_modal/move_to_folder.html b/public/app/features/manage-dashboards/components/MoveToFolderModal/template.html similarity index 100% rename from public/app/features/dashboard/move_to_folder_modal/move_to_folder.html rename to public/app/features/manage-dashboards/components/MoveToFolderModal/template.html diff --git a/public/app/features/manage-dashboards/index.ts b/public/app/features/manage-dashboards/index.ts index 046740904e1..b8c53b3137b 100644 --- a/public/app/features/manage-dashboards/index.ts +++ b/public/app/features/manage-dashboards/index.ts @@ -1,7 +1,15 @@ -import coreModule from 'app/core/core_module'; +export * from './components/MoveToFolderModal'; import { DashboardListCtrl } from './DashboardListCtrl'; import { SnapshotListCtrl } from './SnapshotListCtrl'; +import { FolderDashboardsCtrl } from './FolderDashboardsCtrl'; +import { DashboardImportCtrl } from './DashboardImportCtrl'; +import { CreateFolderCtrl } from './CreateFolderCtrl'; + +import coreModule from 'app/core/core_module'; coreModule.controller('DashboardListCtrl', DashboardListCtrl); coreModule.controller('SnapshotListCtrl', SnapshotListCtrl); +coreModule.controller('FolderDashboardsCtrl', FolderDashboardsCtrl); +coreModule.controller('DashboardImportCtrl', DashboardImportCtrl); +coreModule.controller('CreateFolderCtrl', CreateFolderCtrl); diff --git a/public/app/features/dashboard/folder_page_loader.ts b/public/app/features/manage-dashboards/services/FolderPageLoader.ts similarity index 100% rename from public/app/features/dashboard/folder_page_loader.ts rename to public/app/features/manage-dashboards/services/FolderPageLoader.ts From 5c72e4e66893d997c9c43c312281915dd8e13fbf Mon Sep 17 00:00:00 2001 From: Johannes Schill Date: Wed, 23 Jan 2019 11:27:02 +0100 Subject: [PATCH 16/32] fix: Use custom whitelist for XSS sanitizer to allow class and style attributes --- public/app/core/utils/text.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/public/app/core/utils/text.ts b/public/app/core/utils/text.ts index 9f4f1c41716..427b0102c95 100644 --- a/public/app/core/utils/text.ts +++ b/public/app/core/utils/text.ts @@ -44,9 +44,25 @@ export function findMatchesInText(haystack: string, needle: string): TextMatch[] return matches; } +const XSSWL = Object.keys(xss.whiteList).reduce((acc, element) => { + acc[element] = xss.whiteList[element].concat(['class', 'style']); + return acc; +}, {}); + +const sanitizeXSS = new xss.FilterXSS({ + whiteList: XSSWL +}); + +/** + * Returns string safe from XSS attacks. + * + * Even though we allow the style-attribute, there's still default filtering applied to it + * Info: https://github.com/leizongmin/js-xss#customize-css-filter + * Whitelist: https://github.com/leizongmin/js-css-filter/blob/master/lib/default.js + */ export function sanitize (unsanitizedString: string): string { try { - return xss(unsanitizedString); + return sanitizeXSS.process(unsanitizedString); } catch (error) { console.log('String could not be sanitized', unsanitizedString); return unsanitizedString; From 0c16d3cd6a63d854094890095d1e5d57492ce347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Jan 2019 11:37:46 +0100 Subject: [PATCH 17/32] Moved history component, added start draft of frontend code style guide --- public/app/features/all.ts | 2 +- .../VersionHistory/HistoryListCtrl.test.ts} | 4 +- .../VersionHistory/HistoryListCtrl.ts} | 8 +-- .../VersionHistory/HistorySrv.test.ts} | 7 +-- .../VersionHistory/HistorySrv.ts} | 2 +- .../VersionHistory/__mocks__/history.ts} | 0 .../components/VersionHistory/index.ts | 2 + .../VersionHistory/template.html} | 0 .../features/dashboard/{all.ts => index.ts} | 2 +- style_guides/frontend.md | 62 +++++++++++++++++++ 10 files changed, 75 insertions(+), 14 deletions(-) rename public/app/features/dashboard/{specs/history_ctrl.test.ts => components/VersionHistory/HistoryListCtrl.test.ts} (98%) rename public/app/features/dashboard/{history/history.ts => components/VersionHistory/HistoryListCtrl.ts} (96%) rename public/app/features/dashboard/{specs/history_srv.test.ts => components/VersionHistory/HistorySrv.test.ts} (90%) rename public/app/features/dashboard/{history/history_srv.ts => components/VersionHistory/HistorySrv.ts} (96%) rename public/app/features/dashboard/{specs/history_mocks.ts => components/VersionHistory/__mocks__/history.ts} (100%) create mode 100644 public/app/features/dashboard/components/VersionHistory/index.ts rename public/app/features/dashboard/{history/history.html => components/VersionHistory/template.html} (100%) rename public/app/features/dashboard/{all.ts => index.ts} (96%) create mode 100644 style_guides/frontend.md diff --git a/public/app/features/all.ts b/public/app/features/all.ts index 1ba6a85899c..83146596ea0 100644 --- a/public/app/features/all.ts +++ b/public/app/features/all.ts @@ -1,7 +1,7 @@ import './annotations/all'; import './templating/all'; import './plugins/all'; -import './dashboard/all'; +import './dashboard'; import './playlist/all'; import './panel/all'; import './org/all'; diff --git a/public/app/features/dashboard/specs/history_ctrl.test.ts b/public/app/features/dashboard/components/VersionHistory/HistoryListCtrl.test.ts similarity index 98% rename from public/app/features/dashboard/specs/history_ctrl.test.ts rename to public/app/features/dashboard/components/VersionHistory/HistoryListCtrl.test.ts index 632f3489dae..2b257e148f5 100644 --- a/public/app/features/dashboard/specs/history_ctrl.test.ts +++ b/public/app/features/dashboard/components/VersionHistory/HistoryListCtrl.test.ts @@ -1,6 +1,6 @@ import _ from 'lodash'; -import { HistoryListCtrl } from 'app/features/dashboard/history/history'; -import { versions, compare, restore } from './history_mocks'; +import { HistoryListCtrl } from './HistoryListCtrl'; +import { versions, compare, restore } from './__mocks__/history'; import $q from 'q'; describe('HistoryListCtrl', () => { diff --git a/public/app/features/dashboard/history/history.ts b/public/app/features/dashboard/components/VersionHistory/HistoryListCtrl.ts similarity index 96% rename from public/app/features/dashboard/history/history.ts rename to public/app/features/dashboard/components/VersionHistory/HistoryListCtrl.ts index 3563ccc7766..b8632e2eeae 100644 --- a/public/app/features/dashboard/history/history.ts +++ b/public/app/features/dashboard/components/VersionHistory/HistoryListCtrl.ts @@ -1,12 +1,10 @@ -import './history_srv'; - import _ from 'lodash'; import angular from 'angular'; import moment from 'moment'; import locationUtil from 'app/core/utils/location_util'; -import { DashboardModel } from '../dashboard_model'; -import { HistoryListOpts, RevisionsModel, CalculateDiffOptions, HistorySrv } from './history_srv'; +import { DashboardModel } from '../../dashboard_model'; +import { HistoryListOpts, RevisionsModel, CalculateDiffOptions, HistorySrv } from './HistorySrv'; export class HistoryListCtrl { appending: boolean; @@ -200,7 +198,7 @@ export class HistoryListCtrl { export function dashboardHistoryDirective() { return { restrict: 'E', - templateUrl: 'public/app/features/dashboard/history/history.html', + templateUrl: 'public/app/features/dashboard/components/VersionHistory/template.html', controller: HistoryListCtrl, bindToController: true, controllerAs: 'ctrl', diff --git a/public/app/features/dashboard/specs/history_srv.test.ts b/public/app/features/dashboard/components/VersionHistory/HistorySrv.test.ts similarity index 90% rename from public/app/features/dashboard/specs/history_srv.test.ts rename to public/app/features/dashboard/components/VersionHistory/HistorySrv.test.ts index 1e2bd57a221..75766060e7f 100644 --- a/public/app/features/dashboard/specs/history_srv.test.ts +++ b/public/app/features/dashboard/components/VersionHistory/HistorySrv.test.ts @@ -1,7 +1,6 @@ -import '../history/history_srv'; -import { versions, restore } from './history_mocks'; -import { HistorySrv } from '../history/history_srv'; -import { DashboardModel } from '../dashboard_model'; +import { versions, restore } from './__mocks__/history'; +import { HistorySrv } from './HistorySrv'; +import { DashboardModel } from '../../dashboard_model'; jest.mock('app/core/store'); describe('historySrv', () => { diff --git a/public/app/features/dashboard/history/history_srv.ts b/public/app/features/dashboard/components/VersionHistory/HistorySrv.ts similarity index 96% rename from public/app/features/dashboard/history/history_srv.ts rename to public/app/features/dashboard/components/VersionHistory/HistorySrv.ts index 7f7dc950de3..d52f3ab879c 100644 --- a/public/app/features/dashboard/history/history_srv.ts +++ b/public/app/features/dashboard/components/VersionHistory/HistorySrv.ts @@ -1,6 +1,6 @@ import _ from 'lodash'; import coreModule from 'app/core/core_module'; -import { DashboardModel } from '../dashboard_model'; +import { DashboardModel } from '../../dashboard_model'; export interface HistoryListOpts { limit: number; diff --git a/public/app/features/dashboard/specs/history_mocks.ts b/public/app/features/dashboard/components/VersionHistory/__mocks__/history.ts similarity index 100% rename from public/app/features/dashboard/specs/history_mocks.ts rename to public/app/features/dashboard/components/VersionHistory/__mocks__/history.ts diff --git a/public/app/features/dashboard/components/VersionHistory/index.ts b/public/app/features/dashboard/components/VersionHistory/index.ts new file mode 100644 index 00000000000..138de434bf3 --- /dev/null +++ b/public/app/features/dashboard/components/VersionHistory/index.ts @@ -0,0 +1,2 @@ +export { HistoryListCtrl } from './HistoryListCtrl'; +export { HistorySrv } from './HistorySrv'; diff --git a/public/app/features/dashboard/history/history.html b/public/app/features/dashboard/components/VersionHistory/template.html similarity index 100% rename from public/app/features/dashboard/history/history.html rename to public/app/features/dashboard/components/VersionHistory/template.html diff --git a/public/app/features/dashboard/all.ts b/public/app/features/dashboard/index.ts similarity index 96% rename from public/app/features/dashboard/all.ts rename to public/app/features/dashboard/index.ts index 01570ae4744..316b7c5b443 100644 --- a/public/app/features/dashboard/all.ts +++ b/public/app/features/dashboard/index.ts @@ -1,6 +1,5 @@ import './dashboard_ctrl'; import './alerting_srv'; -import './history/history'; import './dashboard_loader_srv'; import './submenu/submenu'; import './save_as_modal'; @@ -27,6 +26,7 @@ import './components/DashExportModal'; import './components/DashNav'; import './components/ExportDataModal'; import './components/FolderPicker'; +import './components/VersionHistory'; // angular wrappers import { react2AngularDirective } from 'app/core/utils/react2angular'; diff --git a/style_guides/frontend.md b/style_guides/frontend.md new file mode 100644 index 00000000000..8d0849506a3 --- /dev/null +++ b/style_guides/frontend.md @@ -0,0 +1,62 @@ +# Frontend Style Guide + +Generally we follow the Airbnb [React Style Guide](https://github.com/airbnb/javascript/tree/master/react). + +## Table of Contents + + 1. [Basic Rules](#basic-rules) + 1. [File & Component Organization](#Organization) + 1. [Naming](#naming) + 1. [Declaration](#declaration) + 1. [Props](#props) + 1. [Refs](#refs) + 1. [Methods](#methods) + 1. [Ordering](#ordering) + +## Basic rules + +* Try to keep files small and focused and break large components up into sub components. + +## Organization + +* Components and types that needs to be used by external plugins needs to go into @grafana/ui +* Components should get their own folder under features/xxx/components + * Sub components can live in that component folders, so not small component needs their own folder + * Place test next to their component file (same dir) + * Mocks in __mocks__ dir + * Test utils in __tests__ dir + * Component sass should live in the same folder as component code +* State logic & domain models should live in features/xxx/state +* Containers (pages) can live in feature root features/xxx + * up for debate? + +## Props + +* Name callback props & handlers with a "on" prefix. + +```tsx +// good +onChange = () => { + +}; + +render() { + return ( + + ); +} + +// bad +handleChange = () => { + +}; + +render() { + return ( + + ); +} +``` + + + From dfe9252f54d8123531b73b52220eac4ee06e1b8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Jan 2019 11:45:23 +0100 Subject: [PATCH 18/32] Moved dashboard permissions into components dir --- .../DashboardPermissions}/DashboardPermissions.tsx | 4 ++-- public/app/features/dashboard/index.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename public/app/features/dashboard/{permissions => components/DashboardPermissions}/DashboardPermissions.tsx (97%) diff --git a/public/app/features/dashboard/permissions/DashboardPermissions.tsx b/public/app/features/dashboard/components/DashboardPermissions/DashboardPermissions.tsx similarity index 97% rename from public/app/features/dashboard/permissions/DashboardPermissions.tsx rename to public/app/features/dashboard/components/DashboardPermissions/DashboardPermissions.tsx index 96d0e23adcd..506709fad75 100644 --- a/public/app/features/dashboard/permissions/DashboardPermissions.tsx +++ b/public/app/features/dashboard/components/DashboardPermissions/DashboardPermissions.tsx @@ -8,11 +8,11 @@ import { addDashboardPermission, removeDashboardPermission, updateDashboardPermission, -} from '../state/actions'; +} from '../../state/actions'; import PermissionList from 'app/core/components/PermissionList/PermissionList'; import AddPermission from 'app/core/components/PermissionList/AddPermission'; import PermissionsInfo from 'app/core/components/PermissionList/PermissionsInfo'; -import { connectWithStore } from '../../../core/utils/connectWithReduxStore'; +import { connectWithStore } from 'app/core/utils/connectWithReduxStore'; export interface Props { dashboardId: number; diff --git a/public/app/features/dashboard/index.ts b/public/app/features/dashboard/index.ts index 316b7c5b443..2266dd01ad4 100644 --- a/public/app/features/dashboard/index.ts +++ b/public/app/features/dashboard/index.ts @@ -27,10 +27,10 @@ import './components/DashNav'; import './components/ExportDataModal'; import './components/FolderPicker'; import './components/VersionHistory'; +import DashboardPermissions from './components/DashboardPermissions/DashboardPermissions'; // angular wrappers import { react2AngularDirective } from 'app/core/utils/react2angular'; -import DashboardPermissions from './permissions/DashboardPermissions'; react2AngularDirective('dashboardPermissions', DashboardPermissions, ['dashboardId', 'folder']); From 08f7e55ae5c59a2005be50acfb63bfadfc34e224 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Jan 2019 11:48:27 +0100 Subject: [PATCH 19/32] Moved dashboard settings to components --- .../DashboardSettings/SettingsCtrl.ts} | 4 ++-- .../features/dashboard/components/DashboardSettings/index.ts | 1 + .../DashboardSettings/template.html} | 0 public/app/features/dashboard/index.ts | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) rename public/app/features/dashboard/{settings/settings.ts => components/DashboardSettings/SettingsCtrl.ts} (97%) create mode 100644 public/app/features/dashboard/components/DashboardSettings/index.ts rename public/app/features/dashboard/{settings/settings.html => components/DashboardSettings/template.html} (100%) diff --git a/public/app/features/dashboard/settings/settings.ts b/public/app/features/dashboard/components/DashboardSettings/SettingsCtrl.ts similarity index 97% rename from public/app/features/dashboard/settings/settings.ts rename to public/app/features/dashboard/components/DashboardSettings/SettingsCtrl.ts index 1e8d96a54cb..a0eb5c8c6b3 100755 --- a/public/app/features/dashboard/settings/settings.ts +++ b/public/app/features/dashboard/components/DashboardSettings/SettingsCtrl.ts @@ -1,5 +1,5 @@ import { coreModule, appEvents, contextSrv } from 'app/core/core'; -import { DashboardModel } from '../dashboard_model'; +import { DashboardModel } from '../../dashboard_model'; import $ from 'jquery'; import _ from 'lodash'; import angular from 'angular'; @@ -230,7 +230,7 @@ export class SettingsCtrl { export function dashboardSettings() { return { restrict: 'E', - templateUrl: 'public/app/features/dashboard/settings/settings.html', + templateUrl: 'public/app/features/dashboard/components/DashboardSettings/template.html', controller: SettingsCtrl, bindToController: true, controllerAs: 'ctrl', diff --git a/public/app/features/dashboard/components/DashboardSettings/index.ts b/public/app/features/dashboard/components/DashboardSettings/index.ts new file mode 100644 index 00000000000..f81b8cdbc67 --- /dev/null +++ b/public/app/features/dashboard/components/DashboardSettings/index.ts @@ -0,0 +1 @@ +export { SettingsCtrl } from './SettingsCtrl'; diff --git a/public/app/features/dashboard/settings/settings.html b/public/app/features/dashboard/components/DashboardSettings/template.html similarity index 100% rename from public/app/features/dashboard/settings/settings.html rename to public/app/features/dashboard/components/DashboardSettings/template.html diff --git a/public/app/features/dashboard/index.ts b/public/app/features/dashboard/index.ts index 2266dd01ad4..71be50bd413 100644 --- a/public/app/features/dashboard/index.ts +++ b/public/app/features/dashboard/index.ts @@ -19,7 +19,6 @@ import './ad_hoc_filters'; import './repeat_option/repeat_option'; import './dashgrid/DashboardGridDirective'; import './dashgrid/RowOptions'; -import './settings/settings'; import './panellinks/module'; import './components/DashLinks'; import './components/DashExportModal'; @@ -27,6 +26,7 @@ import './components/DashNav'; import './components/ExportDataModal'; import './components/FolderPicker'; import './components/VersionHistory'; +import './components/DashboardSettings'; import DashboardPermissions from './components/DashboardPermissions/DashboardPermissions'; // angular wrappers From 2356057f20e21ccaed004247a5927b03853719c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Jan 2019 11:51:43 +0100 Subject: [PATCH 20/32] Moved submenu into components dir --- .../submenu.ts => components/SubMenu/SubMenuCtrl.ts} | 6 +++--- public/app/features/dashboard/components/SubMenu/index.ts | 1 + .../submenu.html => components/SubMenu/template.html} | 0 public/app/features/dashboard/index.ts | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) rename public/app/features/dashboard/{submenu/submenu.ts => components/SubMenu/SubMenuCtrl.ts} (86%) create mode 100644 public/app/features/dashboard/components/SubMenu/index.ts rename public/app/features/dashboard/{submenu/submenu.html => components/SubMenu/template.html} (100%) diff --git a/public/app/features/dashboard/submenu/submenu.ts b/public/app/features/dashboard/components/SubMenu/SubMenuCtrl.ts similarity index 86% rename from public/app/features/dashboard/submenu/submenu.ts rename to public/app/features/dashboard/components/SubMenu/SubMenuCtrl.ts index 184d29facee..502e467ad2b 100644 --- a/public/app/features/dashboard/submenu/submenu.ts +++ b/public/app/features/dashboard/components/SubMenu/SubMenuCtrl.ts @@ -1,7 +1,7 @@ import angular from 'angular'; import _ from 'lodash'; -export class SubmenuCtrl { +export class SubMenuCtrl { annotations: any; variables: any; dashboard: any; @@ -29,8 +29,8 @@ export class SubmenuCtrl { export function submenuDirective() { return { restrict: 'E', - templateUrl: 'public/app/features/dashboard/submenu/submenu.html', - controller: SubmenuCtrl, + templateUrl: 'public/app/features/dashboard/components/SubMenu/template.html', + controller: SubMenuCtrl, bindToController: true, controllerAs: 'ctrl', scope: { diff --git a/public/app/features/dashboard/components/SubMenu/index.ts b/public/app/features/dashboard/components/SubMenu/index.ts new file mode 100644 index 00000000000..1790aa66782 --- /dev/null +++ b/public/app/features/dashboard/components/SubMenu/index.ts @@ -0,0 +1 @@ +export { SubMenuCtrl } from './SubMenuCtrl'; diff --git a/public/app/features/dashboard/submenu/submenu.html b/public/app/features/dashboard/components/SubMenu/template.html similarity index 100% rename from public/app/features/dashboard/submenu/submenu.html rename to public/app/features/dashboard/components/SubMenu/template.html diff --git a/public/app/features/dashboard/index.ts b/public/app/features/dashboard/index.ts index 71be50bd413..a5f352bcdd8 100644 --- a/public/app/features/dashboard/index.ts +++ b/public/app/features/dashboard/index.ts @@ -1,7 +1,6 @@ import './dashboard_ctrl'; import './alerting_srv'; import './dashboard_loader_srv'; -import './submenu/submenu'; import './save_as_modal'; import './save_modal'; import './save_provisioned_modal'; @@ -27,6 +26,7 @@ import './components/ExportDataModal'; import './components/FolderPicker'; import './components/VersionHistory'; import './components/DashboardSettings'; +import './components/SubMenu'; import DashboardPermissions from './components/DashboardPermissions/DashboardPermissions'; // angular wrappers From ec37f8472709a5cdc3dbef782df67cce0d090ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Jan 2019 11:55:52 +0100 Subject: [PATCH 21/32] Moved timepicker to components --- .../TimePicker/TimePickerCtrl.ts} | 6 +++--- .../app/features/dashboard/components/TimePicker/index.ts | 1 + .../{timepicker => components/TimePicker}/settings.html | 0 .../timepicker.html => components/TimePicker/template.html} | 0 .../input_date.ts => components/TimePicker/validation.ts} | 0 public/app/features/dashboard/index.ts | 2 +- 6 files changed, 5 insertions(+), 4 deletions(-) rename public/app/features/dashboard/{timepicker/timepicker.ts => components/TimePicker/TimePickerCtrl.ts} (95%) create mode 100644 public/app/features/dashboard/components/TimePicker/index.ts rename public/app/features/dashboard/{timepicker => components/TimePicker}/settings.html (100%) rename public/app/features/dashboard/{timepicker/timepicker.html => components/TimePicker/template.html} (100%) rename public/app/features/dashboard/{timepicker/input_date.ts => components/TimePicker/validation.ts} (100%) diff --git a/public/app/features/dashboard/timepicker/timepicker.ts b/public/app/features/dashboard/components/TimePicker/TimePickerCtrl.ts similarity index 95% rename from public/app/features/dashboard/timepicker/timepicker.ts rename to public/app/features/dashboard/components/TimePicker/TimePickerCtrl.ts index c89e49b54b3..0c388c27f8d 100644 --- a/public/app/features/dashboard/timepicker/timepicker.ts +++ b/public/app/features/dashboard/components/TimePicker/TimePickerCtrl.ts @@ -159,7 +159,7 @@ export class TimePickerCtrl { export function settingsDirective() { return { restrict: 'E', - templateUrl: 'public/app/features/dashboard/timepicker/settings.html', + templateUrl: 'public/app/features/dashboard/components/TimePicker/settings.html', controller: TimePickerCtrl, bindToController: true, controllerAs: 'ctrl', @@ -172,7 +172,7 @@ export function settingsDirective() { export function timePickerDirective() { return { restrict: 'E', - templateUrl: 'public/app/features/dashboard/timepicker/timepicker.html', + templateUrl: 'public/app/features/dashboard/components/TimePicker/template.html', controller: TimePickerCtrl, bindToController: true, controllerAs: 'ctrl', @@ -185,5 +185,5 @@ export function timePickerDirective() { angular.module('grafana.directives').directive('gfTimePickerSettings', settingsDirective); angular.module('grafana.directives').directive('gfTimePicker', timePickerDirective); -import { inputDateDirective } from './input_date'; +import { inputDateDirective } from './validation'; angular.module('grafana.directives').directive('inputDatetime', inputDateDirective); diff --git a/public/app/features/dashboard/components/TimePicker/index.ts b/public/app/features/dashboard/components/TimePicker/index.ts new file mode 100644 index 00000000000..ca6e2792c43 --- /dev/null +++ b/public/app/features/dashboard/components/TimePicker/index.ts @@ -0,0 +1 @@ +export { TimePickerCtrl } from './TimePickerCtrl'; diff --git a/public/app/features/dashboard/timepicker/settings.html b/public/app/features/dashboard/components/TimePicker/settings.html similarity index 100% rename from public/app/features/dashboard/timepicker/settings.html rename to public/app/features/dashboard/components/TimePicker/settings.html diff --git a/public/app/features/dashboard/timepicker/timepicker.html b/public/app/features/dashboard/components/TimePicker/template.html similarity index 100% rename from public/app/features/dashboard/timepicker/timepicker.html rename to public/app/features/dashboard/components/TimePicker/template.html diff --git a/public/app/features/dashboard/timepicker/input_date.ts b/public/app/features/dashboard/components/TimePicker/validation.ts similarity index 100% rename from public/app/features/dashboard/timepicker/input_date.ts rename to public/app/features/dashboard/components/TimePicker/validation.ts diff --git a/public/app/features/dashboard/index.ts b/public/app/features/dashboard/index.ts index a5f352bcdd8..692fe50c765 100644 --- a/public/app/features/dashboard/index.ts +++ b/public/app/features/dashboard/index.ts @@ -12,7 +12,6 @@ import './validation_srv'; import './time_srv'; import './unsaved_changes_srv'; import './unsaved_changes_modal'; -import './timepicker/timepicker'; import './upload'; import './ad_hoc_filters'; import './repeat_option/repeat_option'; @@ -27,6 +26,7 @@ import './components/FolderPicker'; import './components/VersionHistory'; import './components/DashboardSettings'; import './components/SubMenu'; +import './components/TimePicker'; import DashboardPermissions from './components/DashboardPermissions/DashboardPermissions'; // angular wrappers From 874792dfcbc49113c286411b093cbeabe0de8d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Jan 2019 12:02:47 +0100 Subject: [PATCH 22/32] Moved view state srv to services --- public/app/features/dashboard/index.ts | 6 +++++- .../DashboardViewStateSrv.test.ts} | 8 +++----- .../DashboardViewStateSrv.ts} | 6 +++--- 3 files changed, 11 insertions(+), 9 deletions(-) rename public/app/features/dashboard/{specs/viewstate_srv.test.ts => services/DashboardViewStateSrv.test.ts} (82%) rename public/app/features/dashboard/{view_state_srv.ts => services/DashboardViewStateSrv.ts} (96%) diff --git a/public/app/features/dashboard/index.ts b/public/app/features/dashboard/index.ts index 692fe50c765..008be67dd67 100644 --- a/public/app/features/dashboard/index.ts +++ b/public/app/features/dashboard/index.ts @@ -7,7 +7,6 @@ import './save_provisioned_modal'; import './shareModalCtrl'; import './share_snapshot_ctrl'; import './dashboard_srv'; -import './view_state_srv'; import './validation_srv'; import './time_srv'; import './unsaved_changes_srv'; @@ -18,6 +17,11 @@ import './repeat_option/repeat_option'; import './dashgrid/DashboardGridDirective'; import './dashgrid/RowOptions'; import './panellinks/module'; + +// Services +import './services/DashboardViewStateSrv'; + +// Components import './components/DashLinks'; import './components/DashExportModal'; import './components/DashNav'; diff --git a/public/app/features/dashboard/specs/viewstate_srv.test.ts b/public/app/features/dashboard/services/DashboardViewStateSrv.test.ts similarity index 82% rename from public/app/features/dashboard/specs/viewstate_srv.test.ts rename to public/app/features/dashboard/services/DashboardViewStateSrv.test.ts index f9963afbf85..aee6746ff36 100644 --- a/public/app/features/dashboard/specs/viewstate_srv.test.ts +++ b/public/app/features/dashboard/services/DashboardViewStateSrv.test.ts @@ -1,7 +1,5 @@ -//import { describe, beforeEach, it, expect, angularMocks } from 'test/lib/common'; -import 'app/features/dashboard/view_state_srv'; import config from 'app/core/config'; -import { DashboardViewState } from '../view_state_srv'; +import { DashboardViewStateSrv } from './DashboardViewStateSrv'; import { DashboardModel } from '../dashboard_model'; describe('when updating view state', () => { @@ -33,7 +31,7 @@ describe('when updating view state', () => { location.search = jest.fn(() => { return { fullscreen: true, edit: true, panelId: 1 }; }); - viewState = new DashboardViewState($scope, location, {}); + viewState = new DashboardViewStateSrv($scope, location, {}); }); it('should update querystring and view state', () => { @@ -55,7 +53,7 @@ describe('when updating view state', () => { describe('to fullscreen false', () => { beforeEach(() => { - viewState = new DashboardViewState($scope, location, {}); + viewState = new DashboardViewStateSrv($scope, location, {}); }); it('should remove params from query string', () => { viewState.update({ fullscreen: true, panelId: 1, edit: true }); diff --git a/public/app/features/dashboard/view_state_srv.ts b/public/app/features/dashboard/services/DashboardViewStateSrv.ts similarity index 96% rename from public/app/features/dashboard/view_state_srv.ts rename to public/app/features/dashboard/services/DashboardViewStateSrv.ts index ff12d26233d..cb9794d6abb 100644 --- a/public/app/features/dashboard/view_state_srv.ts +++ b/public/app/features/dashboard/services/DashboardViewStateSrv.ts @@ -2,11 +2,11 @@ import angular from 'angular'; import _ from 'lodash'; import config from 'app/core/config'; import appEvents from 'app/core/app_events'; -import { DashboardModel } from './dashboard_model'; +import { DashboardModel } from '../dashboard_model'; // represents the transient view state // like fullscreen panel & edit -export class DashboardViewState { +export class DashboardViewStateSrv { state: any; panelScopes: any; $scope: any; @@ -168,7 +168,7 @@ export class DashboardViewState { export function dashboardViewStateSrv($location, $timeout) { return { create: $scope => { - return new DashboardViewState($scope, $location, $timeout); + return new DashboardViewStateSrv($scope, $location, $timeout); }, }; } From a4824085e34f117e008c495343d8ae757e000a80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Jan 2019 12:09:58 +0100 Subject: [PATCH 23/32] Removed unused alertingSrv --- public/app/features/dashboard/alerting_srv.ts | 13 ------------- public/app/features/dashboard/dashboard_ctrl.ts | 2 -- public/app/features/dashboard/index.ts | 1 - 3 files changed, 16 deletions(-) delete mode 100644 public/app/features/dashboard/alerting_srv.ts diff --git a/public/app/features/dashboard/alerting_srv.ts b/public/app/features/dashboard/alerting_srv.ts deleted file mode 100644 index 446c3218f79..00000000000 --- a/public/app/features/dashboard/alerting_srv.ts +++ /dev/null @@ -1,13 +0,0 @@ -import coreModule from 'app/core/core_module'; - -export class AlertingSrv { - dashboard: any; - alerts: any[]; - - init(dashboard, alerts) { - this.dashboard = dashboard; - this.alerts = alerts || []; - } -} - -coreModule.service('alertingSrv', AlertingSrv); diff --git a/public/app/features/dashboard/dashboard_ctrl.ts b/public/app/features/dashboard/dashboard_ctrl.ts index 6611a728803..5c4480dbad5 100644 --- a/public/app/features/dashboard/dashboard_ctrl.ts +++ b/public/app/features/dashboard/dashboard_ctrl.ts @@ -22,7 +22,6 @@ export class DashboardCtrl { private keybindingSrv, private timeSrv, private variableSrv, - private alertingSrv, private dashboardSrv, private unsavedChangesSrv, private dashboardViewStateSrv, @@ -54,7 +53,6 @@ export class DashboardCtrl { // init services this.timeSrv.init(dashboard); - this.alertingSrv.init(dashboard, data.alerts); this.annotationsSrv.init(dashboard); // template values service needs to initialize completely before diff --git a/public/app/features/dashboard/index.ts b/public/app/features/dashboard/index.ts index 008be67dd67..9f319e4900e 100644 --- a/public/app/features/dashboard/index.ts +++ b/public/app/features/dashboard/index.ts @@ -1,5 +1,4 @@ import './dashboard_ctrl'; -import './alerting_srv'; import './dashboard_loader_srv'; import './save_as_modal'; import './save_modal'; From 4358732d21b859e47c7dbab6db9bc10422eb10fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Jan 2019 12:52:46 +0100 Subject: [PATCH 24/32] Moved unsaved changes service and modal --- .../UnsavedChangesModal/UnsavedChangesModalCtrl.ts} | 0 .../dashboard/components/UnsavedChangesModal/index.ts | 1 + public/app/features/dashboard/index.ts | 7 ++++--- .../ChangeTracker.test.ts} | 2 +- .../{change_tracker.ts => services/ChangeTracker.ts} | 2 +- .../UnsavedChangesSrv.ts} | 2 +- 6 files changed, 8 insertions(+), 6 deletions(-) rename public/app/features/dashboard/{unsaved_changes_modal.ts => components/UnsavedChangesModal/UnsavedChangesModalCtrl.ts} (100%) create mode 100644 public/app/features/dashboard/components/UnsavedChangesModal/index.ts rename public/app/features/dashboard/{specs/change_tracker.test.ts => services/ChangeTracker.test.ts} (97%) rename public/app/features/dashboard/{change_tracker.ts => services/ChangeTracker.ts} (98%) rename public/app/features/dashboard/{unsaved_changes_srv.ts => services/UnsavedChangesSrv.ts} (89%) diff --git a/public/app/features/dashboard/unsaved_changes_modal.ts b/public/app/features/dashboard/components/UnsavedChangesModal/UnsavedChangesModalCtrl.ts similarity index 100% rename from public/app/features/dashboard/unsaved_changes_modal.ts rename to public/app/features/dashboard/components/UnsavedChangesModal/UnsavedChangesModalCtrl.ts diff --git a/public/app/features/dashboard/components/UnsavedChangesModal/index.ts b/public/app/features/dashboard/components/UnsavedChangesModal/index.ts new file mode 100644 index 00000000000..43943f06694 --- /dev/null +++ b/public/app/features/dashboard/components/UnsavedChangesModal/index.ts @@ -0,0 +1 @@ +export { UnsavedChangesModalCtrl } from './UnsavedChangesModalCtrl'; diff --git a/public/app/features/dashboard/index.ts b/public/app/features/dashboard/index.ts index 9f319e4900e..a4224ccc5e6 100644 --- a/public/app/features/dashboard/index.ts +++ b/public/app/features/dashboard/index.ts @@ -8,10 +8,8 @@ import './share_snapshot_ctrl'; import './dashboard_srv'; import './validation_srv'; import './time_srv'; -import './unsaved_changes_srv'; -import './unsaved_changes_modal'; -import './upload'; import './ad_hoc_filters'; +import './upload'; import './repeat_option/repeat_option'; import './dashgrid/DashboardGridDirective'; import './dashgrid/RowOptions'; @@ -19,6 +17,7 @@ import './panellinks/module'; // Services import './services/DashboardViewStateSrv'; +import './services/UnsavedChangesSrv'; // Components import './components/DashLinks'; @@ -30,6 +29,8 @@ import './components/VersionHistory'; import './components/DashboardSettings'; import './components/SubMenu'; import './components/TimePicker'; +import './components/UnsavedChangesModal'; + import DashboardPermissions from './components/DashboardPermissions/DashboardPermissions'; // angular wrappers diff --git a/public/app/features/dashboard/specs/change_tracker.test.ts b/public/app/features/dashboard/services/ChangeTracker.test.ts similarity index 97% rename from public/app/features/dashboard/specs/change_tracker.test.ts rename to public/app/features/dashboard/services/ChangeTracker.test.ts index e7f8ce977b1..dfc9b3fa03f 100644 --- a/public/app/features/dashboard/specs/change_tracker.test.ts +++ b/public/app/features/dashboard/services/ChangeTracker.test.ts @@ -1,4 +1,4 @@ -import { ChangeTracker } from 'app/features/dashboard/change_tracker'; +import { ChangeTracker } from './ChangeTracker'; import { contextSrv } from 'app/core/services/context_srv'; import { DashboardModel } from '../dashboard_model'; import { PanelModel } from '../panel_model'; diff --git a/public/app/features/dashboard/change_tracker.ts b/public/app/features/dashboard/services/ChangeTracker.ts similarity index 98% rename from public/app/features/dashboard/change_tracker.ts rename to public/app/features/dashboard/services/ChangeTracker.ts index aa71ac2e306..ef3d456db48 100644 --- a/public/app/features/dashboard/change_tracker.ts +++ b/public/app/features/dashboard/services/ChangeTracker.ts @@ -1,6 +1,6 @@ import angular from 'angular'; import _ from 'lodash'; -import { DashboardModel } from './dashboard_model'; +import { DashboardModel } from '../dashboard_model'; export class ChangeTracker { current: any; diff --git a/public/app/features/dashboard/unsaved_changes_srv.ts b/public/app/features/dashboard/services/UnsavedChangesSrv.ts similarity index 89% rename from public/app/features/dashboard/unsaved_changes_srv.ts rename to public/app/features/dashboard/services/UnsavedChangesSrv.ts index f0a8bf40501..2691cc6ebf8 100644 --- a/public/app/features/dashboard/unsaved_changes_srv.ts +++ b/public/app/features/dashboard/services/UnsavedChangesSrv.ts @@ -1,5 +1,5 @@ import angular from 'angular'; -import { ChangeTracker } from './change_tracker'; +import { ChangeTracker } from './ChangeTracker'; /** @ngInject */ export function unsavedChangesSrv(this: any, $rootScope, $q, $location, $timeout, contextSrv, dashboardSrv, $window) { From 720fa87b89dc80b6a0ee16f471529406c89a477e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Jan 2019 13:00:05 +0100 Subject: [PATCH 25/32] Moved dashboard save modals to components folder --- .../SaveModals/SaveDashboardAsModalCtrl.test.ts} | 2 +- .../SaveModals/SaveDashboardAsModalCtrl.ts} | 0 .../SaveModals/SaveDashboardModalCtrl.test.ts} | 2 +- .../SaveModals/SaveDashboardModalCtrl.ts} | 0 public/app/features/dashboard/components/SaveModals/index.ts | 2 ++ public/app/features/dashboard/index.ts | 5 ++--- .../DashboardLoaderSrv.ts} | 0 7 files changed, 6 insertions(+), 5 deletions(-) rename public/app/features/dashboard/{specs/save_as_modal.test.ts => components/SaveModals/SaveDashboardAsModalCtrl.test.ts} (95%) rename public/app/features/dashboard/{save_as_modal.ts => components/SaveModals/SaveDashboardAsModalCtrl.ts} (100%) rename public/app/features/dashboard/{specs/save_modal.test.ts => components/SaveModals/SaveDashboardModalCtrl.test.ts} (97%) rename public/app/features/dashboard/{save_modal.ts => components/SaveModals/SaveDashboardModalCtrl.ts} (100%) create mode 100644 public/app/features/dashboard/components/SaveModals/index.ts rename public/app/features/dashboard/{dashboard_loader_srv.ts => services/DashboardLoaderSrv.ts} (100%) diff --git a/public/app/features/dashboard/specs/save_as_modal.test.ts b/public/app/features/dashboard/components/SaveModals/SaveDashboardAsModalCtrl.test.ts similarity index 95% rename from public/app/features/dashboard/specs/save_as_modal.test.ts rename to public/app/features/dashboard/components/SaveModals/SaveDashboardAsModalCtrl.test.ts index ceb7e49c550..91b9097b626 100644 --- a/public/app/features/dashboard/specs/save_as_modal.test.ts +++ b/public/app/features/dashboard/components/SaveModals/SaveDashboardAsModalCtrl.test.ts @@ -1,4 +1,4 @@ -import { SaveDashboardAsModalCtrl } from '../save_as_modal'; +import { SaveDashboardAsModalCtrl } from './SaveDashboardAsModalCtrl'; import { describe, it, expect } from 'test/lib/common'; describe('saving dashboard as', () => { diff --git a/public/app/features/dashboard/save_as_modal.ts b/public/app/features/dashboard/components/SaveModals/SaveDashboardAsModalCtrl.ts similarity index 100% rename from public/app/features/dashboard/save_as_modal.ts rename to public/app/features/dashboard/components/SaveModals/SaveDashboardAsModalCtrl.ts diff --git a/public/app/features/dashboard/specs/save_modal.test.ts b/public/app/features/dashboard/components/SaveModals/SaveDashboardModalCtrl.test.ts similarity index 97% rename from public/app/features/dashboard/specs/save_modal.test.ts rename to public/app/features/dashboard/components/SaveModals/SaveDashboardModalCtrl.test.ts index 669ae43a0ff..f973c1b8e63 100644 --- a/public/app/features/dashboard/specs/save_modal.test.ts +++ b/public/app/features/dashboard/components/SaveModals/SaveDashboardModalCtrl.test.ts @@ -1,4 +1,4 @@ -import { SaveDashboardModalCtrl } from '../save_modal'; +import { SaveDashboardModalCtrl } from './SaveDashboardModalCtrl'; const setup = (timeChanged, variableValuesChanged, cb) => { const dash = { diff --git a/public/app/features/dashboard/save_modal.ts b/public/app/features/dashboard/components/SaveModals/SaveDashboardModalCtrl.ts similarity index 100% rename from public/app/features/dashboard/save_modal.ts rename to public/app/features/dashboard/components/SaveModals/SaveDashboardModalCtrl.ts diff --git a/public/app/features/dashboard/components/SaveModals/index.ts b/public/app/features/dashboard/components/SaveModals/index.ts new file mode 100644 index 00000000000..afab0796d28 --- /dev/null +++ b/public/app/features/dashboard/components/SaveModals/index.ts @@ -0,0 +1,2 @@ +export { SaveDashboardAsModalCtrl } from './SaveDashboardAsModalCtrl'; +export { SaveDashboardModalCtrl } from './SaveDashboardModalCtrl'; diff --git a/public/app/features/dashboard/index.ts b/public/app/features/dashboard/index.ts index a4224ccc5e6..3183b0d8959 100644 --- a/public/app/features/dashboard/index.ts +++ b/public/app/features/dashboard/index.ts @@ -1,7 +1,4 @@ import './dashboard_ctrl'; -import './dashboard_loader_srv'; -import './save_as_modal'; -import './save_modal'; import './save_provisioned_modal'; import './shareModalCtrl'; import './share_snapshot_ctrl'; @@ -18,6 +15,7 @@ import './panellinks/module'; // Services import './services/DashboardViewStateSrv'; import './services/UnsavedChangesSrv'; +import './services/DashboardLoaderSrv'; // Components import './components/DashLinks'; @@ -30,6 +28,7 @@ import './components/DashboardSettings'; import './components/SubMenu'; import './components/TimePicker'; import './components/UnsavedChangesModal'; +import './components/SaveModals'; import DashboardPermissions from './components/DashboardPermissions/DashboardPermissions'; diff --git a/public/app/features/dashboard/dashboard_loader_srv.ts b/public/app/features/dashboard/services/DashboardLoaderSrv.ts similarity index 100% rename from public/app/features/dashboard/dashboard_loader_srv.ts rename to public/app/features/dashboard/services/DashboardLoaderSrv.ts From 80da19010e414447520fb42a95ce07bf23c76a53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Jan 2019 13:07:20 +0100 Subject: [PATCH 26/32] Moved share modal --- public/app/core/services/keybindingSrv.ts | 2 +- .../app/features/dashboard/components/DashNav/DashNavCtrl.ts | 2 +- .../SaveModals/SaveProvisionedDashboardModalCtrl.test.ts} | 2 +- .../SaveModals/SaveProvisionedDashboardModalCtrl.ts} | 0 .../ShareModal/ShareModalCtrl.test.ts} | 3 +-- .../ShareModal/ShareModalCtrl.ts} | 0 public/app/features/dashboard/components/ShareModal/index.ts | 1 + .../shareModal.html => components/ShareModal/template.html} | 0 public/app/features/dashboard/index.ts | 3 +-- public/app/features/dashboard/utils/panel.ts | 2 +- 10 files changed, 7 insertions(+), 8 deletions(-) rename public/app/features/dashboard/{specs/save_provisioned_modal.test.ts => components/SaveModals/SaveProvisionedDashboardModalCtrl.test.ts} (87%) rename public/app/features/dashboard/{save_provisioned_modal.ts => components/SaveModals/SaveProvisionedDashboardModalCtrl.ts} (100%) rename public/app/features/dashboard/{specs/share_modal_ctrl.test.ts => components/ShareModal/ShareModalCtrl.test.ts} (98%) rename public/app/features/dashboard/{shareModalCtrl.ts => components/ShareModal/ShareModalCtrl.ts} (100%) create mode 100644 public/app/features/dashboard/components/ShareModal/index.ts rename public/app/features/dashboard/{partials/shareModal.html => components/ShareModal/template.html} (100%) diff --git a/public/app/core/services/keybindingSrv.ts b/public/app/core/services/keybindingSrv.ts index 9e128c449a6..989746fd067 100644 --- a/public/app/core/services/keybindingSrv.ts +++ b/public/app/core/services/keybindingSrv.ts @@ -236,7 +236,7 @@ export class KeybindingSrv { shareScope.dashboard = dashboard; appEvents.emit('show-modal', { - src: 'public/app/features/dashboard/partials/shareModal.html', + src: 'public/app/features/dashboard/components/ShareModal/template.html', scope: shareScope, }); } diff --git a/public/app/features/dashboard/components/DashNav/DashNavCtrl.ts b/public/app/features/dashboard/components/DashNav/DashNavCtrl.ts index 0f28bb0afdb..d7305b948dc 100644 --- a/public/app/features/dashboard/components/DashNav/DashNavCtrl.ts +++ b/public/app/features/dashboard/components/DashNav/DashNavCtrl.ts @@ -60,7 +60,7 @@ export class DashNavCtrl { modalScope.dashboard = this.dashboard; appEvents.emit('show-modal', { - src: 'public/app/features/dashboard/partials/shareModal.html', + src: 'public/app/features/dashboard/components/ShareModal/template.html', scope: modalScope, }); } diff --git a/public/app/features/dashboard/specs/save_provisioned_modal.test.ts b/public/app/features/dashboard/components/SaveModals/SaveProvisionedDashboardModalCtrl.test.ts similarity index 87% rename from public/app/features/dashboard/specs/save_provisioned_modal.test.ts rename to public/app/features/dashboard/components/SaveModals/SaveProvisionedDashboardModalCtrl.test.ts index a3ab27a984f..86048e861bd 100644 --- a/public/app/features/dashboard/specs/save_provisioned_modal.test.ts +++ b/public/app/features/dashboard/components/SaveModals/SaveProvisionedDashboardModalCtrl.test.ts @@ -1,4 +1,4 @@ -import { SaveProvisionedDashboardModalCtrl } from '../save_provisioned_modal'; +import { SaveProvisionedDashboardModalCtrl } from './SaveProvisionedDashboardModalCtrl'; describe('SaveProvisionedDashboardModalCtrl', () => { const json = { diff --git a/public/app/features/dashboard/save_provisioned_modal.ts b/public/app/features/dashboard/components/SaveModals/SaveProvisionedDashboardModalCtrl.ts similarity index 100% rename from public/app/features/dashboard/save_provisioned_modal.ts rename to public/app/features/dashboard/components/SaveModals/SaveProvisionedDashboardModalCtrl.ts diff --git a/public/app/features/dashboard/specs/share_modal_ctrl.test.ts b/public/app/features/dashboard/components/ShareModal/ShareModalCtrl.test.ts similarity index 98% rename from public/app/features/dashboard/specs/share_modal_ctrl.test.ts rename to public/app/features/dashboard/components/ShareModal/ShareModalCtrl.test.ts index 70d301ed5ff..dd8dac31dde 100644 --- a/public/app/features/dashboard/specs/share_modal_ctrl.test.ts +++ b/public/app/features/dashboard/components/ShareModal/ShareModalCtrl.test.ts @@ -1,7 +1,6 @@ -import '../shareModalCtrl'; -import { ShareModalCtrl } from '../shareModalCtrl'; import config from 'app/core/config'; import { LinkSrv } from 'app/features/dashboard/panellinks/link_srv'; +import { ShareModalCtrl } from './ShareModalCtrl'; describe('ShareModalCtrl', () => { const ctx = { diff --git a/public/app/features/dashboard/shareModalCtrl.ts b/public/app/features/dashboard/components/ShareModal/ShareModalCtrl.ts similarity index 100% rename from public/app/features/dashboard/shareModalCtrl.ts rename to public/app/features/dashboard/components/ShareModal/ShareModalCtrl.ts diff --git a/public/app/features/dashboard/components/ShareModal/index.ts b/public/app/features/dashboard/components/ShareModal/index.ts new file mode 100644 index 00000000000..053f40c8278 --- /dev/null +++ b/public/app/features/dashboard/components/ShareModal/index.ts @@ -0,0 +1 @@ +export { ShareModalCtrl } from './ShareModalCtrl'; diff --git a/public/app/features/dashboard/partials/shareModal.html b/public/app/features/dashboard/components/ShareModal/template.html similarity index 100% rename from public/app/features/dashboard/partials/shareModal.html rename to public/app/features/dashboard/components/ShareModal/template.html diff --git a/public/app/features/dashboard/index.ts b/public/app/features/dashboard/index.ts index 3183b0d8959..3887e10629e 100644 --- a/public/app/features/dashboard/index.ts +++ b/public/app/features/dashboard/index.ts @@ -1,6 +1,4 @@ import './dashboard_ctrl'; -import './save_provisioned_modal'; -import './shareModalCtrl'; import './share_snapshot_ctrl'; import './dashboard_srv'; import './validation_srv'; @@ -29,6 +27,7 @@ import './components/SubMenu'; import './components/TimePicker'; import './components/UnsavedChangesModal'; import './components/SaveModals'; +import './components/ShareModal'; import DashboardPermissions from './components/DashboardPermissions/DashboardPermissions'; diff --git a/public/app/features/dashboard/utils/panel.ts b/public/app/features/dashboard/utils/panel.ts index 00c960bdfaa..cfbe094125f 100644 --- a/public/app/features/dashboard/utils/panel.ts +++ b/public/app/features/dashboard/utils/panel.ts @@ -80,7 +80,7 @@ export const editPanelJson = (dashboard: DashboardModel, panel: PanelModel) => { export const sharePanel = (dashboard: DashboardModel, panel: PanelModel) => { appEvents.emit('show-modal', { - src: 'public/app/features/dashboard/partials/shareModal.html', + src: 'public/app/features/dashboard/components/ShareModal/template.html', model: { dashboard: dashboard, panel: panel, From 2f08c56260c371bd72f5be7a763db5f28ec4b6e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Jan 2019 13:10:49 +0100 Subject: [PATCH 27/32] Moved dashboard srv and snapshot ctrl --- .../ShareModal/ShareSnapshotCtrl.ts} | 0 public/app/features/dashboard/components/ShareModal/index.ts | 1 + public/app/features/dashboard/index.ts | 3 +-- .../dashboard/{dashboard_srv.ts => services/DashboardSrv.ts} | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename public/app/features/dashboard/{share_snapshot_ctrl.ts => components/ShareModal/ShareSnapshotCtrl.ts} (100%) rename public/app/features/dashboard/{dashboard_srv.ts => services/DashboardSrv.ts} (98%) diff --git a/public/app/features/dashboard/share_snapshot_ctrl.ts b/public/app/features/dashboard/components/ShareModal/ShareSnapshotCtrl.ts similarity index 100% rename from public/app/features/dashboard/share_snapshot_ctrl.ts rename to public/app/features/dashboard/components/ShareModal/ShareSnapshotCtrl.ts diff --git a/public/app/features/dashboard/components/ShareModal/index.ts b/public/app/features/dashboard/components/ShareModal/index.ts index 053f40c8278..3f27d5a1ba3 100644 --- a/public/app/features/dashboard/components/ShareModal/index.ts +++ b/public/app/features/dashboard/components/ShareModal/index.ts @@ -1 +1,2 @@ export { ShareModalCtrl } from './ShareModalCtrl'; +export { ShareSnapshotCtrl } from './ShareSnapshotCtrl'; diff --git a/public/app/features/dashboard/index.ts b/public/app/features/dashboard/index.ts index 3887e10629e..fab23d4641f 100644 --- a/public/app/features/dashboard/index.ts +++ b/public/app/features/dashboard/index.ts @@ -1,6 +1,4 @@ import './dashboard_ctrl'; -import './share_snapshot_ctrl'; -import './dashboard_srv'; import './validation_srv'; import './time_srv'; import './ad_hoc_filters'; @@ -14,6 +12,7 @@ import './panellinks/module'; import './services/DashboardViewStateSrv'; import './services/UnsavedChangesSrv'; import './services/DashboardLoaderSrv'; +import './services/DashboardSrv'; // Components import './components/DashLinks'; diff --git a/public/app/features/dashboard/dashboard_srv.ts b/public/app/features/dashboard/services/DashboardSrv.ts similarity index 98% rename from public/app/features/dashboard/dashboard_srv.ts rename to public/app/features/dashboard/services/DashboardSrv.ts index d5695a577c5..67a4938c6aa 100644 --- a/public/app/features/dashboard/dashboard_srv.ts +++ b/public/app/features/dashboard/services/DashboardSrv.ts @@ -1,5 +1,5 @@ import coreModule from 'app/core/core_module'; -import { DashboardModel } from './dashboard_model'; +import { DashboardModel } from '../dashboard_model'; import locationUtil from 'app/core/utils/location_util'; export class DashboardSrv { From f0eef79c1a7c29209392bfcf54441f53dbac56e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Jan 2019 13:31:45 +0100 Subject: [PATCH 28/32] Moved ad hoc filters and upload directive --- .../AdHocFilters/AdHocFiltersCtrl.ts} | 0 .../features/dashboard/components/AdHocFilters/index.ts | 1 + public/app/features/dashboard/index.ts | 4 +--- .../manage-dashboards/components/UploadDashboard/index.ts | 1 + .../UploadDashboard/uploadDashboardDirective.ts} | 2 +- public/app/features/manage-dashboards/index.ts | 8 +++++++- .../services/ValidationSrv.ts} | 0 7 files changed, 11 insertions(+), 5 deletions(-) rename public/app/features/dashboard/{ad_hoc_filters.ts => components/AdHocFilters/AdHocFiltersCtrl.ts} (100%) create mode 100644 public/app/features/dashboard/components/AdHocFilters/index.ts create mode 100644 public/app/features/manage-dashboards/components/UploadDashboard/index.ts rename public/app/features/{dashboard/upload.ts => manage-dashboards/components/UploadDashboard/uploadDashboardDirective.ts} (96%) rename public/app/features/{dashboard/validation_srv.ts => manage-dashboards/services/ValidationSrv.ts} (100%) diff --git a/public/app/features/dashboard/ad_hoc_filters.ts b/public/app/features/dashboard/components/AdHocFilters/AdHocFiltersCtrl.ts similarity index 100% rename from public/app/features/dashboard/ad_hoc_filters.ts rename to public/app/features/dashboard/components/AdHocFilters/AdHocFiltersCtrl.ts diff --git a/public/app/features/dashboard/components/AdHocFilters/index.ts b/public/app/features/dashboard/components/AdHocFilters/index.ts new file mode 100644 index 00000000000..522b564d004 --- /dev/null +++ b/public/app/features/dashboard/components/AdHocFilters/index.ts @@ -0,0 +1 @@ +export { AdHocFiltersCtrl } from './AdHocFiltersCtrl'; diff --git a/public/app/features/dashboard/index.ts b/public/app/features/dashboard/index.ts index fab23d4641f..79831cd4015 100644 --- a/public/app/features/dashboard/index.ts +++ b/public/app/features/dashboard/index.ts @@ -1,8 +1,5 @@ import './dashboard_ctrl'; -import './validation_srv'; import './time_srv'; -import './ad_hoc_filters'; -import './upload'; import './repeat_option/repeat_option'; import './dashgrid/DashboardGridDirective'; import './dashgrid/RowOptions'; @@ -27,6 +24,7 @@ import './components/TimePicker'; import './components/UnsavedChangesModal'; import './components/SaveModals'; import './components/ShareModal'; +import './components/AdHocFilters'; import DashboardPermissions from './components/DashboardPermissions/DashboardPermissions'; diff --git a/public/app/features/manage-dashboards/components/UploadDashboard/index.ts b/public/app/features/manage-dashboards/components/UploadDashboard/index.ts new file mode 100644 index 00000000000..828b4f76982 --- /dev/null +++ b/public/app/features/manage-dashboards/components/UploadDashboard/index.ts @@ -0,0 +1 @@ +export { uploadDashboardDirective } from './uploadDashboardDirective'; diff --git a/public/app/features/dashboard/upload.ts b/public/app/features/manage-dashboards/components/UploadDashboard/uploadDashboardDirective.ts similarity index 96% rename from public/app/features/dashboard/upload.ts rename to public/app/features/manage-dashboards/components/UploadDashboard/uploadDashboardDirective.ts index ec4ad9a03cb..0c38a1247f1 100644 --- a/public/app/features/dashboard/upload.ts +++ b/public/app/features/manage-dashboards/components/UploadDashboard/uploadDashboardDirective.ts @@ -11,7 +11,7 @@ const template = ` `; /** @ngInject */ -function uploadDashboardDirective(timer, $location) { +export function uploadDashboardDirective(timer, $location) { return { restrict: 'E', template: template, diff --git a/public/app/features/manage-dashboards/index.ts b/public/app/features/manage-dashboards/index.ts index b8c53b3137b..c3830ee6546 100644 --- a/public/app/features/manage-dashboards/index.ts +++ b/public/app/features/manage-dashboards/index.ts @@ -1,5 +1,11 @@ -export * from './components/MoveToFolderModal'; +// Services +export { ValidationSrv } from './services/ValidationSrv'; +// Components +export * from './components/MoveToFolderModal'; +export * from './components/UploadDashboard'; + +// Controllers import { DashboardListCtrl } from './DashboardListCtrl'; import { SnapshotListCtrl } from './SnapshotListCtrl'; import { FolderDashboardsCtrl } from './FolderDashboardsCtrl'; diff --git a/public/app/features/dashboard/validation_srv.ts b/public/app/features/manage-dashboards/services/ValidationSrv.ts similarity index 100% rename from public/app/features/dashboard/validation_srv.ts rename to public/app/features/manage-dashboards/services/ValidationSrv.ts From c0277ab595c165523067afbc724edd8677058249 Mon Sep 17 00:00:00 2001 From: David Kaltschmidt Date: Wed, 23 Jan 2019 15:05:54 +0100 Subject: [PATCH 29/32] Explore: Fix scanning for logs - Redux migration caused the scanner to not be set - this change adds the setting/unsetting of the scanner in the reducer - added test --- .../features/explore/state/reducers.test.ts | 42 +++++++++++++++++++ public/app/features/explore/state/reducers.ts | 16 ++++--- 2 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 public/app/features/explore/state/reducers.test.ts diff --git a/public/app/features/explore/state/reducers.test.ts b/public/app/features/explore/state/reducers.test.ts new file mode 100644 index 00000000000..8227a947c5b --- /dev/null +++ b/public/app/features/explore/state/reducers.test.ts @@ -0,0 +1,42 @@ +import { Action, ActionTypes } from './actionTypes'; +import { itemReducer, makeExploreItemState } from './reducers'; +import { ExploreId } from 'app/types/explore'; + +describe('Explore item reducer', () => { + describe('scanning', () => { + test('should start scanning', () => { + let state = makeExploreItemState(); + const action: Action = { + type: ActionTypes.ScanStart, + payload: { + exploreId: ExploreId.left, + scanner: jest.fn(), + }, + }; + state = itemReducer(state, action); + expect(state.scanning).toBeTruthy(); + expect(state.scanner).toBe(action.payload.scanner); + }); + test('should stop scanning', () => { + let state = makeExploreItemState(); + const start: Action = { + type: ActionTypes.ScanStart, + payload: { + exploreId: ExploreId.left, + scanner: jest.fn(), + }, + }; + state = itemReducer(state, start); + expect(state.scanning).toBeTruthy(); + const action: Action = { + type: ActionTypes.ScanStop, + payload: { + exploreId: ExploreId.left, + }, + }; + state = itemReducer(state, action); + expect(state.scanning).toBeFalsy(); + expect(state.scanner).toBeUndefined(); + }); + }); +}); diff --git a/public/app/features/explore/state/reducers.ts b/public/app/features/explore/state/reducers.ts index 8acf52340c9..8885f972d06 100644 --- a/public/app/features/explore/state/reducers.ts +++ b/public/app/features/explore/state/reducers.ts @@ -20,7 +20,7 @@ const DEFAULT_GRAPH_INTERVAL = 15 * 1000; /** * Returns a fresh Explore area state */ -const makeExploreItemState = (): ExploreItemState => ({ +export const makeExploreItemState = (): ExploreItemState => ({ StartPage: undefined, containerWidth: 0, datasourceInstance: null, @@ -48,7 +48,7 @@ const makeExploreItemState = (): ExploreItemState => ({ /** * Global Explore state that handles multiple Explore areas and the split state */ -const initialExploreState: ExploreState = { +export const initialExploreState: ExploreState = { split: null, left: makeExploreItemState(), right: makeExploreItemState(), @@ -57,7 +57,7 @@ const initialExploreState: ExploreState = { /** * Reducer for an Explore area, to be used by the global Explore reducer. */ -const itemReducer = (state, action: Action): ExploreItemState => { +export const itemReducer = (state, action: Action): ExploreItemState => { switch (action.type) { case ActionTypes.AddQueryRow: { const { initialQueries, modifiedQueries, queryTransactions } = state; @@ -360,13 +360,19 @@ const itemReducer = (state, action: Action): ExploreItemState => { } case ActionTypes.ScanStart: { - return { ...state, scanning: true }; + return { ...state, scanning: true, scanner: action.payload.scanner }; } case ActionTypes.ScanStop: { const { queryTransactions } = state; const nextQueryTransactions = queryTransactions.filter(qt => qt.scanning && !qt.done); - return { ...state, queryTransactions: nextQueryTransactions, scanning: false, scanRange: undefined }; + return { + ...state, + queryTransactions: nextQueryTransactions, + scanning: false, + scanRange: undefined, + scanner: undefined, + }; } case ActionTypes.SetQueries: { From 05a976fdb19c1ac4b3c0785a34fd16fd54c417aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Jan 2019 18:24:57 +0100 Subject: [PATCH 30/32] added docs entry for check_for_updates config flag, fixes ##14940 --- docs/sources/installation/configuration.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/sources/installation/configuration.md b/docs/sources/installation/configuration.md index 8fa51c88554..46bab83654e 100644 --- a/docs/sources/installation/configuration.md +++ b/docs/sources/installation/configuration.md @@ -391,6 +391,12 @@ value is `true`. If you want to track Grafana usage via Google analytics specify *your* Universal Analytics ID here. By default this feature is disabled. +### check_for_updates + +Set to false to disable all checks to https://grafana.com for new versions of Grafana and installed plugins. Check is used +in some UI views to notify that a Grafana or plugin update exists. This option does not cause any auto updates, nor +send any sensitive information. +
## [dashboards] From b1ef3c43f9b85c21cb62c2be8346d6e8b286cc54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Jan 2019 19:34:56 +0100 Subject: [PATCH 31/32] Disable query should trigger refresh --- public/app/features/dashboard/panel_editor/QueryEditorRow.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/public/app/features/dashboard/panel_editor/QueryEditorRow.tsx b/public/app/features/dashboard/panel_editor/QueryEditorRow.tsx index 540b6a8353e..2651ab0608c 100644 --- a/public/app/features/dashboard/panel_editor/QueryEditorRow.tsx +++ b/public/app/features/dashboard/panel_editor/QueryEditorRow.tsx @@ -166,6 +166,7 @@ export class QueryEditorRow extends PureComponent { onDisableQuery = () => { this.props.query.hide = !this.props.query.hide; + this.onExecuteQuery(); this.forceUpdate(); }; From 6419a303778fd5ef2bcf00cf4bd716b694d1d357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Wed, 23 Jan 2019 21:19:42 +0100 Subject: [PATCH 32/32] Fixed react key warning for loki start page --- .../app/plugins/datasource/loki/components/LokiCheatSheet.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/plugins/datasource/loki/components/LokiCheatSheet.tsx b/public/app/plugins/datasource/loki/components/LokiCheatSheet.tsx index 49f6b74e8b6..a7b865cde3f 100644 --- a/public/app/plugins/datasource/loki/components/LokiCheatSheet.tsx +++ b/public/app/plugins/datasource/loki/components/LokiCheatSheet.tsx @@ -26,7 +26,7 @@ export default (props: any) => (

Loki Cheat Sheet

{CHEAT_SHEET_ITEMS.map(item => ( -
+
{item.title}
{item.expression && (