Skip to content

Commit d47ffa6

Browse files
gurinder39GurinderRawala
authored andcommitted
confirm grafana initialization (#107)
* window event to confirm initialization * grafana start up status events
1 parent 15c970b commit d47ffa6

File tree

1 file changed

+131
-36
lines changed

1 file changed

+131
-36
lines changed

public/app/fn_app.ts

+131-36
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1+
import 'symbol-observable';
12
import 'core-js';
23
import 'regenerator-runtime/runtime';
3-
import 'symbol-observable';
44

5-
import 'file-saver';
6-
import 'jquery';
75
import 'whatwg-fetch'; // fetch polyfill needed for PhantomJs rendering
86
import './polyfills/old-mediaquerylist'; // Safari < 14 does not have mql.addEventListener()
7+
import 'file-saver';
8+
import 'jquery';
99

1010
import 'app/features/all';
11+
1112
import _ from 'lodash'; // eslint-disable-line lodash/import-scope
1213

1314
import {
@@ -28,19 +29,28 @@ import {
2829
setEchoSrv,
2930
setLocationSrv,
3031
setQueryRunnerFactory,
32+
setRunRequest,
33+
setPluginImportUtils,
34+
setPluginExtensionGetter,
35+
setAppEvents,
36+
type GetPluginExtensions,
3137
} from '@grafana/runtime';
3238
import { setPanelDataErrorView } from '@grafana/runtime/src/components/PanelDataErrorView';
3339
import { setPanelRenderer } from '@grafana/runtime/src/components/PanelRenderer';
40+
import { setPluginPage } from '@grafana/runtime/src/components/PluginPage';
3441
import { getScrollbarWidth } from '@grafana/ui';
3542
import config, { Settings } from 'app/core/config';
3643
import { arrayMove } from 'app/core/utils/arrayMove';
3744
import { getStandardTransformers } from 'app/features/transformers/standardTransformers';
3845

3946
import getDefaultMonacoLanguages from '../lib/monaco-languages';
4047

48+
import appEvents from './core/app_events';
4149
import { AppChromeService } from './core/components/AppChrome/AppChromeService';
4250
import { getAllOptionEditors, getAllStandardFieldConfigs } from './core/components/OptionsUI/registry';
51+
import { PluginPage } from './core/components/Page/PluginPage';
4352
import { GrafanaContextType } from './core/context/GrafanaContext';
53+
import { initializeI18n } from './core/internationalization';
4454
import { interceptLinkClicks } from './core/navigation/patch/interceptLinkClicks';
4555
import { ModalManager } from './core/services/ModalManager';
4656
import { backendSrv } from './core/services/backend_srv';
@@ -49,18 +59,25 @@ import { Echo } from './core/services/echo/Echo';
4959
import { reportPerformance } from './core/services/echo/EchoSrv';
5060
import { PerformanceBackend } from './core/services/echo/backends/PerformanceBackend';
5161
import { ApplicationInsightsBackend } from './core/services/echo/backends/analytics/ApplicationInsightsBackend';
52-
import { GAEchoBackend } from './core/services/echo/backends/analytics/GABackend';
62+
// import { GA4EchoBackend } from './core/services/echo/backends/analytics/GA4Backend';
63+
// import { GAEchoBackend } from './core/services/echo/backends/analytics/GABackend';
5364
import { RudderstackBackend } from './core/services/echo/backends/analytics/RudderstackBackend';
5465
import { GrafanaJavascriptAgentBackend } from './core/services/echo/backends/grafana-javascript-agent/GrafanaJavascriptAgentBackend';
55-
import { SentryEchoBackend } from './core/services/echo/backends/sentry/SentryBackend';
56-
import { initializeI18n } from './core/internationalization';
66+
import { KeybindingSrv } from './core/services/keybindingSrv';
67+
import { startMeasure, stopMeasure } from './core/utils/metrics';
5768
import { initDevFeatures } from './dev';
5869
import { getTimeSrv } from './features/dashboard/services/TimeSrv';
70+
// import { initGrafanaLive } from './features/live';
5971
import { PanelDataErrorView } from './features/panel/components/PanelDataErrorView';
6072
import { PanelRenderer } from './features/panel/components/PanelRenderer';
6173
import { DatasourceSrv } from './features/plugins/datasource_srv';
74+
import { createPluginExtensionRegistry } from './features/plugins/extensions/createPluginExtensionRegistry';
75+
import { getCoreExtensionConfigurations } from './features/plugins/extensions/getCoreExtensionConfigurations';
76+
import { getPluginExtensions } from './features/plugins/extensions/getPluginExtensions';
77+
import { importPanelPlugin, syncGetPanelPlugin } from './features/plugins/importPanelPlugin';
6278
import { preloadPlugins } from './features/plugins/pluginPreloader';
6379
import { QueryRunner } from './features/query/state/QueryRunner';
80+
import { runRequest } from './features/query/state/runRequest';
6481
import { initWindowRuntime } from './features/runtime/init';
6582
import { variableAdapters } from './features/variables/adapters';
6683
import { createAdHocVariableAdapter } from './features/variables/adhoc/adapter';
@@ -73,7 +90,7 @@ import { setVariableQueryRunner, VariableQueryRunner } from './features/variable
7390
import { createQueryVariableAdapter } from './features/variables/query/adapter';
7491
import { createSystemVariableAdapter } from './features/variables/system/adapter';
7592
import { createTextBoxVariableAdapter } from './features/variables/textbox/adapter';
76-
import { ConfiguredStore, configureStore } from './store/configureStore';
93+
import { configureStore } from './store/configureStore';
7794

7895
// add move to lodash for backward compatabilty with plugins
7996
// @ts-ignore
@@ -89,16 +106,42 @@ if (process.env.NODE_ENV === 'development') {
89106
initDevFeatures();
90107
}
91108

109+
export declare type FNGrafanaStartupState = {
110+
isLoading: boolean;
111+
isError: boolean;
112+
error?: unknown;
113+
isIdeal: boolean;
114+
};
115+
116+
export const DefaultGrafanaStartupState: FNGrafanaStartupState = {
117+
isLoading: false,
118+
isError: false,
119+
isIdeal: true,
120+
};
121+
122+
const dispatchFnEvent = (info: FNGrafanaStartupState = DefaultGrafanaStartupState, ek = 'grafana-startup') => {
123+
window.dispatchEvent(
124+
new CustomEvent(ek, {
125+
detail: info,
126+
})
127+
);
128+
};
129+
92130
export class GrafanaApp {
93131
context!: GrafanaContextType;
94-
readonly store: ConfiguredStore;
95-
96-
constructor() {
97-
this.store = configureStore();
98-
}
99132

100133
async init() {
101134
try {
135+
dispatchFnEvent({
136+
isIdeal: false,
137+
isLoading: true,
138+
isError: false,
139+
});
140+
// Let iframe container know grafana has started loading
141+
parent.postMessage('GrafanaAppInit', '*');
142+
143+
const initI18nPromise = initializeI18n(config.bootData.user.language);
144+
102145
backendSrv.setGrafanaPrefix(true);
103146
setBackendSrv(backendSrv);
104147
const settings: Settings = await backendSrv.get('/api/frontend/settings');
@@ -107,18 +150,28 @@ export class GrafanaApp {
107150
config.datasources = settings.datasources;
108151
config.defaultDatasource = settings.defaultDatasource;
109152

110-
initializeI18n(config.bootData.user.locale);
111-
112153
initEchoSrv();
154+
// This needs to be done after the `initEchoSrv` since it is being used under the hood.
155+
startMeasure('frontend_app_init');
113156
addClassIfNoOverlayScrollbar();
114157
setLocale(config.bootData.user.locale);
115158
setWeekStart(config.bootData.user.weekStart);
116159
setPanelRenderer(PanelRenderer);
160+
setPluginPage(PluginPage);
117161
setPanelDataErrorView(PanelDataErrorView);
118162
setLocationSrv(locationService);
119163
setTimeZoneResolver(() => config.bootData.user.timezone);
164+
// initGrafanaLive();
165+
166+
// Expose the app-wide eventbus
167+
setAppEvents(appEvents);
168+
169+
// We must wait for translations to load because some preloaded store state requires translating
170+
await initI18nPromise;
171+
120172
// Important that extension reducers are initialized before store
121173
addExtensionReducers();
174+
configureStore();
122175
initExtensions();
123176

124177
standardEditorsRegistry.setInit(getAllOptionEditors);
@@ -139,6 +192,15 @@ export class GrafanaApp {
139192
setQueryRunnerFactory(() => new QueryRunner());
140193
setVariableQueryRunner(new VariableQueryRunner());
141194

195+
// Provide runRequest implementation to packages, @grafana/scenes in particular
196+
setRunRequest(runRequest);
197+
198+
// Privide plugin import utils to packages, @grafana/scenes in particular
199+
setPluginImportUtils({
200+
importPanelPlugin,
201+
getPanelPluginFromCache: syncGetPanelPlugin,
202+
});
203+
142204
locationUtil.initialize({
143205
config,
144206
getTimeRangeForUrl: getTimeSrv().timeRangeForUrl,
@@ -159,20 +221,52 @@ export class GrafanaApp {
159221
modalManager.init();
160222

161223
// Preload selected app plugins
162-
await preloadPlugins(config.pluginsToPreload);
224+
const preloadResults = await preloadPlugins(config.apps);
225+
226+
// Create extension registry out of preloaded plugins and core extensions
227+
const extensionRegistry = createPluginExtensionRegistry([
228+
{ pluginId: 'grafana', extensionConfigs: getCoreExtensionConfigurations() },
229+
...preloadResults,
230+
]);
231+
232+
// Expose the getPluginExtension function via grafana-runtime
233+
const pluginExtensionGetter: GetPluginExtensions = (options) =>
234+
getPluginExtensions({ ...options, registry: extensionRegistry });
235+
236+
setPluginExtensionGetter(pluginExtensionGetter);
237+
238+
// initialize chrome service
239+
const queryParams = locationService.getSearchObject();
240+
const chromeService = new AppChromeService();
241+
const keybindingsService = new KeybindingSrv(locationService, chromeService);
242+
243+
// Read initial kiosk mode from url at app startup
244+
chromeService.setKioskModeFromUrl(queryParams.kiosk);
163245

164246
this.context = {
165247
backend: backendSrv,
166248
location: locationService,
167-
chrome: new AppChromeService(),
249+
chrome: chromeService,
250+
keybindings: keybindingsService,
168251
config,
169252
};
253+
254+
dispatchFnEvent({
255+
isLoading: false,
256+
isError: false,
257+
isIdeal: false,
258+
});
170259
} catch (error) {
260+
dispatchFnEvent({
261+
isLoading: false,
262+
isError: true,
263+
error,
264+
isIdeal: false,
265+
});
171266
console.error('Failed to start Grafana', error);
172-
173-
if (window.__grafana_load_failed) {
174-
window.__grafana_load_failed();
175-
}
267+
window.__grafana_load_failed();
268+
} finally {
269+
stopMeasure('frontend_app_init');
176270
}
177271
}
178272
}
@@ -212,15 +306,6 @@ function initEchoSrv() {
212306
registerEchoBackend(new PerformanceBackend({}));
213307
}
214308

215-
if (config.sentry.enabled) {
216-
registerEchoBackend(
217-
new SentryEchoBackend({
218-
...config.sentry,
219-
user: config.bootData.user,
220-
buildInfo: config.buildInfo,
221-
})
222-
);
223-
}
224309
if (config.grafanaJavascriptAgent.enabled) {
225310
registerEchoBackend(
226311
new GrafanaJavascriptAgentBackend({
@@ -238,13 +323,22 @@ function initEchoSrv() {
238323
);
239324
}
240325

241-
if (config.googleAnalyticsId) {
242-
registerEchoBackend(
243-
new GAEchoBackend({
244-
googleAnalyticsId: config.googleAnalyticsId,
245-
})
246-
);
247-
}
326+
// if (config.googleAnalyticsId) {
327+
// registerEchoBackend(
328+
// new GAEchoBackend({
329+
// googleAnalyticsId: config.googleAnalyticsId,
330+
// })
331+
// );
332+
// }
333+
334+
// if (config.googleAnalytics4Id) {
335+
// registerEchoBackend(
336+
// new GA4EchoBackend({
337+
// googleAnalyticsId: config.googleAnalytics4Id,
338+
// googleAnalytics4SendManualPageViews: config.googleAnalytics4SendManualPageViews,
339+
// })
340+
// );
341+
// }
248342

249343
if (config.rudderstackWriteKey && config.rudderstackDataPlaneUrl) {
250344
registerEchoBackend(
@@ -254,6 +348,7 @@ function initEchoSrv() {
254348
user: config.bootData.user,
255349
sdkUrl: config.rudderstackSdkUrl,
256350
configUrl: config.rudderstackConfigUrl,
351+
buildInfo: config.buildInfo,
257352
})
258353
);
259354
}

0 commit comments

Comments
 (0)