From 4d4eb354b72860bea3d376f5c95a839aad19f37c Mon Sep 17 00:00:00 2001 From: Tarek Becker Date: Thu, 1 Nov 2018 21:43:07 +0100 Subject: [PATCH 1/4] Add [hash] to filename of grafana.{light,dark}.css --- public/views/index.template.html | 2 +- scripts/webpack/webpack.dev.js | 2 +- scripts/webpack/webpack.prod.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/public/views/index.template.html b/public/views/index.template.html index 1f6e511784d..096684d3e37 100644 --- a/public/views/index.template.html +++ b/public/views/index.template.html @@ -15,7 +15,7 @@ - + diff --git a/scripts/webpack/webpack.dev.js b/scripts/webpack/webpack.dev.js index 7eecceeb1bf..5cef1b6afd4 100644 --- a/scripts/webpack/webpack.dev.js +++ b/scripts/webpack/webpack.dev.js @@ -80,7 +80,7 @@ module.exports = merge(common, { plugins: [ new CleanWebpackPlugin('../../public/build', { allowExternal: true }), new MiniCssExtractPlugin({ - filename: "grafana.[name].css" + filename: "grafana.[name].[hash].css" }), new HtmlWebpackPlugin({ filename: path.resolve(__dirname, '../../public/views/index.html'), diff --git a/scripts/webpack/webpack.prod.js b/scripts/webpack/webpack.prod.js index 9e1e4cfb0b5..761d22892ea 100644 --- a/scripts/webpack/webpack.prod.js +++ b/scripts/webpack/webpack.prod.js @@ -71,7 +71,7 @@ module.exports = merge(common, { plugins: [ new MiniCssExtractPlugin({ - filename: "grafana.[name].css" + filename: "grafana.[name].[hash].css" }), new ngAnnotatePlugin(), new HtmlWebpackPlugin({ From 70bb81c6eb6db2648d59385df9f5902a72489423 Mon Sep 17 00:00:00 2001 From: Tarek Becker Date: Thu, 1 Nov 2018 23:31:17 +0100 Subject: [PATCH 2/4] Load hash based styles in error.html, too --- .gitignore | 1 + public/views/{error.html => error.template.html} | 2 +- scripts/webpack/webpack.common.js | 2 +- scripts/webpack/webpack.dev.js | 5 +++++ scripts/webpack/webpack.prod.js | 5 +++++ 5 files changed, 13 insertions(+), 2 deletions(-) rename public/views/{error.html => error.template.html} (98%) diff --git a/.gitignore b/.gitignore index 21083741e14..05ae4907e89 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ awsconfig /dist /public/build /public/views/index.html +/public/views/error.html /emails/dist /public_gen /public/vendor/npm diff --git a/public/views/error.html b/public/views/error.template.html similarity index 98% rename from public/views/error.html rename to public/views/error.template.html index 5c51e28eff4..af430fc6c3d 100644 --- a/public/views/error.html +++ b/public/views/error.template.html @@ -10,7 +10,7 @@ - + diff --git a/scripts/webpack/webpack.common.js b/scripts/webpack/webpack.common.js index dc4a7f363a2..7da6c3559bf 100644 --- a/scripts/webpack/webpack.common.js +++ b/scripts/webpack/webpack.common.js @@ -47,7 +47,7 @@ module.exports = { }, { test: /\.html$/, - exclude: /index\.template.html/, + exclude: /(index|error)\.template\.html/, use: [ { loader: 'ngtemplate-loader?relativeTo=' + (path.resolve(__dirname, '../../public')) + '&prefix=public' }, { diff --git a/scripts/webpack/webpack.dev.js b/scripts/webpack/webpack.dev.js index 5cef1b6afd4..456cc277f2f 100644 --- a/scripts/webpack/webpack.dev.js +++ b/scripts/webpack/webpack.dev.js @@ -82,6 +82,11 @@ module.exports = merge(common, { new MiniCssExtractPlugin({ filename: "grafana.[name].[hash].css" }), + new HtmlWebpackPlugin({ + filename: path.resolve(__dirname, '../../public/views/error.html'), + template: path.resolve(__dirname, '../../public/views/error.template.html'), + inject: 'false', + }), new HtmlWebpackPlugin({ filename: path.resolve(__dirname, '../../public/views/index.html'), template: path.resolve(__dirname, '../../public/views/index.template.html'), diff --git a/scripts/webpack/webpack.prod.js b/scripts/webpack/webpack.prod.js index 761d22892ea..c4b4b27245e 100644 --- a/scripts/webpack/webpack.prod.js +++ b/scripts/webpack/webpack.prod.js @@ -80,6 +80,11 @@ module.exports = merge(common, { inject: 'body', chunks: ['vendor', 'app'], }), + new HtmlWebpackPlugin({ + filename: path.resolve(__dirname, '../../public/views/error.html'), + template: path.resolve(__dirname, '../../public/views/error.template.html'), + inject: false, + }), function () { this.hooks.done.tap('Done', function (stats) { if (stats.compilation.errors && stats.compilation.errors.length) { From b415d826116c567ac89313055d792873a7ff39b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 2 Nov 2018 10:49:46 +0100 Subject: [PATCH 3/4] fixed to template PR issues, #13938 --- pkg/middleware/middleware_test.go | 1 + pkg/middleware/recovery.go | 2 +- pkg/middleware/recovery_test.go | 4 ++ pkg/models/context.go | 2 +- pkg/setting/setting.go | 4 ++ .../dashboard/specs/panel_model.test.ts | 72 +++++++++++++++++++ ...rror.template.html => error-template.html} | 0 ...ndex.template.html => index-template.html} | 0 scripts/webpack/webpack.common.js | 2 +- scripts/webpack/webpack.dev.js | 4 +- scripts/webpack/webpack.hot.js | 2 +- scripts/webpack/webpack.prod.js | 4 +- 12 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 public/app/features/dashboard/specs/panel_model.test.ts rename public/views/{error.template.html => error-template.html} (100%) rename public/views/{index.template.html => index-template.html} (100%) diff --git a/pkg/middleware/middleware_test.go b/pkg/middleware/middleware_test.go index 1830b3eb161..e9a3c8059f8 100644 --- a/pkg/middleware/middleware_test.go +++ b/pkg/middleware/middleware_test.go @@ -18,6 +18,7 @@ import ( ) func TestMiddlewareContext(t *testing.T) { + setting.ERR_TEMPLATE_NAME = "error-template" Convey("Given the grafana middleware", t, func() { middlewareScenario("middleware should add context to injector", func(sc *scenarioContext) { diff --git a/pkg/middleware/recovery.go b/pkg/middleware/recovery.go index 456bc91354e..eef07c8c24a 100644 --- a/pkg/middleware/recovery.go +++ b/pkg/middleware/recovery.go @@ -138,7 +138,7 @@ func Recovery() macaron.Handler { c.JSON(500, resp) } else { - c.HTML(500, "error") + c.HTML(500, setting.ERR_TEMPLATE_NAME) } } }() diff --git a/pkg/middleware/recovery_test.go b/pkg/middleware/recovery_test.go index 4bbedbc3b21..c92150f3b7d 100644 --- a/pkg/middleware/recovery_test.go +++ b/pkg/middleware/recovery_test.go @@ -8,11 +8,14 @@ import ( "github.com/grafana/grafana/pkg/bus" m "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/session" + "github.com/grafana/grafana/pkg/setting" . "github.com/smartystreets/goconvey/convey" "gopkg.in/macaron.v1" ) func TestRecoveryMiddleware(t *testing.T) { + setting.ERR_TEMPLATE_NAME = "error-template" + Convey("Given an api route that panics", t, func() { apiURL := "/api/whatever" recoveryScenario("recovery middleware should return json", apiURL, func(sc *scenarioContext) { @@ -50,6 +53,7 @@ func recoveryScenario(desc string, url string, fn scenarioFunc) { sc := &scenarioContext{ url: url, } + viewsPath, _ := filepath.Abs("../../public/views") sc.m = macaron.New() diff --git a/pkg/models/context.go b/pkg/models/context.go index 262f6550954..c78028665a6 100644 --- a/pkg/models/context.go +++ b/pkg/models/context.go @@ -36,7 +36,7 @@ func (ctx *ReqContext) Handle(status int, title string, err error) { ctx.Data["AppSubUrl"] = setting.AppSubUrl ctx.Data["Theme"] = "dark" - ctx.HTML(status, "error") + ctx.HTML(status, setting.ERR_TEMPLATE_NAME) } func (ctx *ReqContext) JsonOK(message string) { diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index 9e8f6fec9a8..afae642f5b3 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -38,6 +38,10 @@ const ( APP_NAME_ENTERPRISE = "Grafana Enterprise" ) +var ( + ERR_TEMPLATE_NAME = "error" +) + var ( // App settings. Env = DEV diff --git a/public/app/features/dashboard/specs/panel_model.test.ts b/public/app/features/dashboard/specs/panel_model.test.ts new file mode 100644 index 00000000000..b1e31ce3f91 --- /dev/null +++ b/public/app/features/dashboard/specs/panel_model.test.ts @@ -0,0 +1,72 @@ +import _ from 'lodash'; +import { PanelModel } from '../panel_model'; + +describe('PanelModel', () => { + describe('when creating new panel model', () => { + let model; + + beforeEach(() => { + model = new PanelModel({}); + }); + + it('should apply defaults', () => { + expect(model.gridPos.h).toBe(3); + }); + + it('getSaveModel should remove defaults', () => { + const saveModel = model.getSaveModel(); + expect(saveModel.gridPos).toBe(undefined); + }); + + it('getSaveModel should remove nonPersistedProperties', () => { + const saveModel = model.getSaveModel(); + expect(saveModel.events).toBe(undefined); + }); + + describe('when calling applyDefaults', () => { + beforeEach(() => { + const defaults = { + myName: 'My name', + myBool1: true, + myBool2: false, + myNumber: 0, + nestedObj: { + myName: 'nested name', + myBool1: true, + myBool2: false, + myNumber: 0, + }, + }; + model.applyDefaults(defaults); + }); + + it('Should apply defaults', () => { + expect(model.myName).toBe('My name'); + expect(model.myBool1).toBe(true); + expect(model.myBool2).toBe(false); + expect(model.myNumber).toBe(0); + expect(model.nestedObj.myName).toBe('nested name'); + expect(model.nestedObj.myBool1).toBe(true); + expect(model.nestedObj.myBool2).toBe(false); + expect(model.nestedObj.myNumber).toBe(0); + }); + + it('getSaveModel should remove them', () => { + const saveModel = model.getSaveModel(); + expect(saveModel.myName).toBe(undefined); + expect(saveModel.nestedObj).toBe(undefined); + }); + + it('getSaveModel should remove only unchanged defaults', () => { + model.myName = 'changed'; + model.nestedObj.myBool2 = true; + + const saveModel = model.getSaveModel(); + + expect(saveModel.myName).toBe('changed'); + expect(saveModel.nestedObj.myBool2).toBe(true); + expect(saveModel.nestedObj.myBool1).toBe(undefined); + }); + }); + }); +}); diff --git a/public/views/error.template.html b/public/views/error-template.html similarity index 100% rename from public/views/error.template.html rename to public/views/error-template.html diff --git a/public/views/index.template.html b/public/views/index-template.html similarity index 100% rename from public/views/index.template.html rename to public/views/index-template.html diff --git a/scripts/webpack/webpack.common.js b/scripts/webpack/webpack.common.js index 7da6c3559bf..ae7222e8374 100644 --- a/scripts/webpack/webpack.common.js +++ b/scripts/webpack/webpack.common.js @@ -47,7 +47,7 @@ module.exports = { }, { test: /\.html$/, - exclude: /(index|error)\.template\.html/, + exclude: /(index|error)\-template\.html/, use: [ { loader: 'ngtemplate-loader?relativeTo=' + (path.resolve(__dirname, '../../public')) + '&prefix=public' }, { diff --git a/scripts/webpack/webpack.dev.js b/scripts/webpack/webpack.dev.js index 456cc277f2f..228df79b3f8 100644 --- a/scripts/webpack/webpack.dev.js +++ b/scripts/webpack/webpack.dev.js @@ -84,12 +84,12 @@ module.exports = merge(common, { }), new HtmlWebpackPlugin({ filename: path.resolve(__dirname, '../../public/views/error.html'), - template: path.resolve(__dirname, '../../public/views/error.template.html'), + template: path.resolve(__dirname, '../../public/views/error-template.html'), inject: 'false', }), new HtmlWebpackPlugin({ filename: path.resolve(__dirname, '../../public/views/index.html'), - template: path.resolve(__dirname, '../../public/views/index.template.html'), + template: path.resolve(__dirname, '../../public/views/index-template.html'), inject: 'body', chunks: ['manifest', 'vendor', 'app'], }), diff --git a/scripts/webpack/webpack.hot.js b/scripts/webpack/webpack.hot.js index 0305a6f465c..dd3cc8c1190 100644 --- a/scripts/webpack/webpack.hot.js +++ b/scripts/webpack/webpack.hot.js @@ -87,7 +87,7 @@ module.exports = merge(common, { new CleanWebpackPlugin('../public/build', { allowExternal: true }), new HtmlWebpackPlugin({ filename: path.resolve(__dirname, '../../public/views/index.html'), - template: path.resolve(__dirname, '../../public/views/index.template.html'), + template: path.resolve(__dirname, '../../public/views/index-template.html'), inject: 'body', alwaysWriteToDisk: true }), diff --git a/scripts/webpack/webpack.prod.js b/scripts/webpack/webpack.prod.js index c4b4b27245e..5d3ffa61219 100644 --- a/scripts/webpack/webpack.prod.js +++ b/scripts/webpack/webpack.prod.js @@ -76,13 +76,13 @@ module.exports = merge(common, { new ngAnnotatePlugin(), new HtmlWebpackPlugin({ filename: path.resolve(__dirname, '../../public/views/index.html'), - template: path.resolve(__dirname, '../../public/views/index.template.html'), + template: path.resolve(__dirname, '../../public/views/index-template.html'), inject: 'body', chunks: ['vendor', 'app'], }), new HtmlWebpackPlugin({ filename: path.resolve(__dirname, '../../public/views/error.html'), - template: path.resolve(__dirname, '../../public/views/error.template.html'), + template: path.resolve(__dirname, '../../public/views/error-template.html'), inject: false, }), function () { From 61ff9fe603c1ad815f3a7b7cb12c5a1beeb64c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 2 Nov 2018 11:13:56 +0100 Subject: [PATCH 4/4] removed file I added accidentally --- .../dashboard/specs/panel_model.test.ts | 72 ------------------- 1 file changed, 72 deletions(-) delete mode 100644 public/app/features/dashboard/specs/panel_model.test.ts diff --git a/public/app/features/dashboard/specs/panel_model.test.ts b/public/app/features/dashboard/specs/panel_model.test.ts deleted file mode 100644 index b1e31ce3f91..00000000000 --- a/public/app/features/dashboard/specs/panel_model.test.ts +++ /dev/null @@ -1,72 +0,0 @@ -import _ from 'lodash'; -import { PanelModel } from '../panel_model'; - -describe('PanelModel', () => { - describe('when creating new panel model', () => { - let model; - - beforeEach(() => { - model = new PanelModel({}); - }); - - it('should apply defaults', () => { - expect(model.gridPos.h).toBe(3); - }); - - it('getSaveModel should remove defaults', () => { - const saveModel = model.getSaveModel(); - expect(saveModel.gridPos).toBe(undefined); - }); - - it('getSaveModel should remove nonPersistedProperties', () => { - const saveModel = model.getSaveModel(); - expect(saveModel.events).toBe(undefined); - }); - - describe('when calling applyDefaults', () => { - beforeEach(() => { - const defaults = { - myName: 'My name', - myBool1: true, - myBool2: false, - myNumber: 0, - nestedObj: { - myName: 'nested name', - myBool1: true, - myBool2: false, - myNumber: 0, - }, - }; - model.applyDefaults(defaults); - }); - - it('Should apply defaults', () => { - expect(model.myName).toBe('My name'); - expect(model.myBool1).toBe(true); - expect(model.myBool2).toBe(false); - expect(model.myNumber).toBe(0); - expect(model.nestedObj.myName).toBe('nested name'); - expect(model.nestedObj.myBool1).toBe(true); - expect(model.nestedObj.myBool2).toBe(false); - expect(model.nestedObj.myNumber).toBe(0); - }); - - it('getSaveModel should remove them', () => { - const saveModel = model.getSaveModel(); - expect(saveModel.myName).toBe(undefined); - expect(saveModel.nestedObj).toBe(undefined); - }); - - it('getSaveModel should remove only unchanged defaults', () => { - model.myName = 'changed'; - model.nestedObj.myBool2 = true; - - const saveModel = model.getSaveModel(); - - expect(saveModel.myName).toBe('changed'); - expect(saveModel.nestedObj.myBool2).toBe(true); - expect(saveModel.nestedObj.myBool1).toBe(undefined); - }); - }); - }); -});