mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Preparation for High Contrast Mode, Kibana-Management domains (#202607)
## Summary **Reviewers: Please test the code paths affected by this PR. See the "Risks" section below.** Part of work for enabling "high contrast mode" in Kibana. See https://github.com/elastic/kibana/issues/176219 **Background:** Kibana will soon have a user profile setting to allow users to enable "high contrast mode." This setting will activate a flag with `<EuiProvider>` that causes EUI components to render with higher contrast visual elements. Consumer plugins and packages need to be updated selected places where `<EuiProvider>` is wrapped, to pass the `UserProfileService` service dependency from the CoreStart contract. ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [X] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [X] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) ### Risks Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss. Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging. - [ ] [medium/high] The implementor of this change did not manually test the affected code paths and relied on type-checking and functional tests to drive the changes. Code owners for this PR need to manually test the affected code paths. - [ ] [medium] The `UserProfileService` dependency comes from the CoreStart contract. If acquiring the service causes synchronous code to become asynchronous, check for race conditions or errors in rendering React components. Code owners for this PR need to manually test the affected code paths.
This commit is contained in:
parent
56be0c6984
commit
1fe184b165
29 changed files with 80 additions and 29 deletions
|
@ -27,6 +27,7 @@ export const KibanaSettingsApplication = ({
|
|||
i18n,
|
||||
notifications,
|
||||
settings,
|
||||
userProfile,
|
||||
theme,
|
||||
history,
|
||||
sectionRegistry,
|
||||
|
@ -36,6 +37,7 @@ export const KibanaSettingsApplication = ({
|
|||
<SettingsApplicationKibanaProvider
|
||||
{...{
|
||||
settings,
|
||||
userProfile,
|
||||
theme,
|
||||
i18n,
|
||||
notifications,
|
||||
|
|
|
@ -11,6 +11,7 @@ import React, { ReactChild } from 'react';
|
|||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
|
||||
import { KibanaRootContextProvider } from '@kbn/react-kibana-context-root';
|
||||
import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks';
|
||||
import { themeServiceMock } from '@kbn/core-theme-browser-mocks';
|
||||
import { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks';
|
||||
import { I18nStart } from '@kbn/core-i18n-browser';
|
||||
|
@ -31,10 +32,12 @@ const createRootMock = () => {
|
|||
Context: ({ children }) => <I18nProvider>{children}</I18nProvider>,
|
||||
};
|
||||
const theme = themeServiceMock.createStartContract();
|
||||
const userProfile = userProfileServiceMock.createStart();
|
||||
return {
|
||||
analytics,
|
||||
i18n,
|
||||
theme,
|
||||
userProfile,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -121,6 +121,7 @@ export const SettingsApplicationKibanaProvider: FC<
|
|||
const {
|
||||
docLinks,
|
||||
notifications,
|
||||
userProfile,
|
||||
theme,
|
||||
i18n,
|
||||
settings,
|
||||
|
@ -194,7 +195,7 @@ export const SettingsApplicationKibanaProvider: FC<
|
|||
|
||||
return (
|
||||
<SettingsApplicationContext.Provider value={services}>
|
||||
<FormKibanaProvider {...{ docLinks, notifications, theme, i18n, settings }}>
|
||||
<FormKibanaProvider {...{ docLinks, notifications, userProfile, theme, i18n, settings }}>
|
||||
{children}
|
||||
</FormKibanaProvider>
|
||||
</SettingsApplicationContext.Provider>
|
||||
|
|
|
@ -35,5 +35,6 @@
|
|||
"@kbn/management-settings-section-registry",
|
||||
"@kbn/core-notifications-browser",
|
||||
"@kbn/core-chrome-browser",
|
||||
"@kbn/core-user-profile-browser-mocks",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import { I18nProvider } from '@kbn/i18n-react';
|
|||
import { KibanaRootContextProvider } from '@kbn/react-kibana-context-root';
|
||||
import { themeServiceMock } from '@kbn/core-theme-browser-mocks';
|
||||
import { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks';
|
||||
import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks';
|
||||
import { I18nStart } from '@kbn/core-i18n-browser';
|
||||
|
||||
import { FieldInputProvider } from '../services';
|
||||
|
@ -20,6 +21,7 @@ import { FieldInputServices } from '../types';
|
|||
|
||||
const createRootMock = () => {
|
||||
const analytics = analyticsServiceMock.createAnalyticsServiceStart();
|
||||
const userProfile = userProfileServiceMock.createStart();
|
||||
const i18n: I18nStart = {
|
||||
Context: ({ children }) => <I18nProvider>{children}</I18nProvider>,
|
||||
};
|
||||
|
@ -28,6 +30,7 @@ const createRootMock = () => {
|
|||
analytics,
|
||||
i18n,
|
||||
theme,
|
||||
userProfile,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -30,5 +30,6 @@
|
|||
"@kbn/core-analytics-browser-mocks",
|
||||
"@kbn/core-ui-settings-browser",
|
||||
"@kbn/code-editor",
|
||||
"@kbn/core-user-profile-browser-mocks",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import React, { ReactChild } from 'react';
|
|||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
|
||||
import { KibanaRootContextProvider } from '@kbn/react-kibana-context-root';
|
||||
import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks';
|
||||
import { themeServiceMock } from '@kbn/core-theme-browser-mocks';
|
||||
import { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks';
|
||||
import { I18nStart } from '@kbn/core-i18n-browser';
|
||||
|
@ -26,10 +27,12 @@ const createRootMock = () => {
|
|||
Context: ({ children }) => <I18nProvider>{children}</I18nProvider>,
|
||||
};
|
||||
const theme = themeServiceMock.createStartContract();
|
||||
const userProfile = userProfileServiceMock.createStart();
|
||||
return {
|
||||
analytics,
|
||||
i18n,
|
||||
theme,
|
||||
userProfile,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -30,5 +30,6 @@
|
|||
"@kbn/core-theme-browser-mocks",
|
||||
"@kbn/core-i18n-browser",
|
||||
"@kbn/core-analytics-browser-mocks",
|
||||
"@kbn/core-user-profile-browser-mocks",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import React, { ReactChild } from 'react';
|
|||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
|
||||
import { KibanaRootContextProvider } from '@kbn/react-kibana-context-root';
|
||||
import { userProfileServiceMock } from '@kbn/core-user-profile-browser-mocks';
|
||||
import { themeServiceMock } from '@kbn/core-theme-browser-mocks';
|
||||
import { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks';
|
||||
import { I18nStart } from '@kbn/core-i18n-browser';
|
||||
|
@ -25,10 +26,12 @@ const createRootMock = () => {
|
|||
Context: ({ children }) => <I18nProvider>{children}</I18nProvider>,
|
||||
};
|
||||
const theme = themeServiceMock.createStartContract();
|
||||
const userProfile = userProfileServiceMock.createStart();
|
||||
return {
|
||||
analytics,
|
||||
i18n,
|
||||
theme,
|
||||
userProfile,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -15,16 +15,23 @@ import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
|||
import { ToastInput } from '@kbn/core-notifications-browser';
|
||||
import { I18nStart } from '@kbn/core-i18n-browser';
|
||||
import { ThemeServiceStart } from '@kbn/core-theme-browser';
|
||||
import type { UserProfileService } from '@kbn/core-user-profile-browser';
|
||||
|
||||
export const DATA_TEST_SUBJ_PAGE_RELOAD_BUTTON = 'pageReloadButton';
|
||||
|
||||
interface StartDeps {
|
||||
theme: ThemeServiceStart;
|
||||
i18n: I18nStart;
|
||||
userProfile: UserProfileService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function for returning a {@link ToastInput} for displaying a prompt for reloading the page.
|
||||
* @param theme The {@link ThemeServiceStart} contract.
|
||||
* @param i18nStart The {@link I18nStart} contract.
|
||||
* @returns A toast.
|
||||
*/
|
||||
export const reloadPageToast = (theme: ThemeServiceStart, i18nStart: I18nStart): ToastInput => {
|
||||
export const reloadPageToast = (startDeps: StartDeps): ToastInput => {
|
||||
return {
|
||||
title: i18n.translate('management.settings.form.requiresPageReloadToastDescription', {
|
||||
defaultMessage: 'One or more settings require you to reload the page to take effect.',
|
||||
|
@ -43,7 +50,7 @@ export const reloadPageToast = (theme: ThemeServiceStart, i18nStart: I18nStart):
|
|||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>,
|
||||
{ i18n: i18nStart, theme }
|
||||
startDeps
|
||||
),
|
||||
color: 'success',
|
||||
toastLifeTimeMs: 15000,
|
||||
|
|
|
@ -46,7 +46,7 @@ export const FormKibanaProvider: FC<PropsWithChildren<FormKibanaDependencies>> =
|
|||
children,
|
||||
...deps
|
||||
}) => {
|
||||
const { settings, notifications, docLinks, theme, i18n } = deps;
|
||||
const { settings, notifications, docLinks, ...startDeps } = deps;
|
||||
|
||||
const services: Services = {
|
||||
saveChanges: (changes, scope: UiSettingsScope) => {
|
||||
|
@ -57,7 +57,7 @@ export const FormKibanaProvider: FC<PropsWithChildren<FormKibanaDependencies>> =
|
|||
return Promise.all(arr);
|
||||
},
|
||||
showError: (message: string) => notifications.toasts.addDanger(message),
|
||||
showReloadPagePrompt: () => notifications.toasts.add(reloadPageToast(theme, i18n)),
|
||||
showReloadPagePrompt: () => notifications.toasts.add(reloadPageToast(startDeps)),
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
@ -34,5 +34,7 @@
|
|||
"@kbn/management-settings-utilities",
|
||||
"@kbn/core-analytics-browser-mocks",
|
||||
"@kbn/core-ui-settings-common",
|
||||
"@kbn/core-user-profile-browser-mocks",
|
||||
"@kbn/core-user-profile-browser",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import { I18nStart } from '@kbn/core-i18n-browser';
|
|||
import { ThemeServiceStart } from '@kbn/core-theme-browser';
|
||||
import { ToastsStart } from '@kbn/core-notifications-browser';
|
||||
import { UiSettingsScope } from '@kbn/core-ui-settings-common';
|
||||
import { UserProfileService } from '@kbn/core-user-profile-browser';
|
||||
|
||||
/**
|
||||
* Contextual services used by a {@link Form} component.
|
||||
|
@ -42,6 +43,7 @@ interface KibanaDependencies {
|
|||
globalClient: Pick<IUiSettingsClient, 'set'>;
|
||||
};
|
||||
theme: ThemeServiceStart;
|
||||
userProfile: UserProfileService;
|
||||
i18n: I18nStart;
|
||||
/** The portion of the {@link ToastsStart} contract used by this component. */
|
||||
notifications: {
|
||||
|
|
|
@ -8,7 +8,12 @@
|
|||
*/
|
||||
|
||||
import type { FC } from 'react';
|
||||
import type { AnalyticsServiceStart, I18nStart, ThemeServiceStart } from '@kbn/core/public';
|
||||
import type {
|
||||
AnalyticsServiceStart,
|
||||
I18nStart,
|
||||
ThemeServiceStart,
|
||||
UserProfileService,
|
||||
} from '@kbn/core/public';
|
||||
import { HomePublicPluginSetup, HomePublicPluginStart } from '@kbn/home-plugin/public';
|
||||
import { DevToolsSetup } from '@kbn/dev-tools-plugin/public';
|
||||
import { UsageCollectionSetup, UsageCollectionStart } from '@kbn/usage-collection-plugin/public';
|
||||
|
@ -21,6 +26,7 @@ export interface ConsoleStartServices {
|
|||
analytics: Pick<AnalyticsServiceStart, 'reportEvent'>;
|
||||
i18n: I18nStart;
|
||||
theme: Pick<ThemeServiceStart, 'theme$'>;
|
||||
userProfile: UserProfileService;
|
||||
}
|
||||
|
||||
export interface AppSetupUIPluginDependencies {
|
||||
|
|
|
@ -66,8 +66,8 @@ export class DevToolsPlugin implements Plugin<DevToolsSetup, void> {
|
|||
|
||||
const [core] = await getStartServices();
|
||||
const { application, chrome, executionContext } = core;
|
||||
const { analytics, i18n: i18nStart, theme } = core;
|
||||
const startServices = { analytics, i18n: i18nStart, theme };
|
||||
const { analytics, i18n: i18nStart, theme, userProfile } = core;
|
||||
const startServices = { analytics, i18n: i18nStart, theme, userProfile };
|
||||
|
||||
this.docTitleService.setup(chrome.docTitle.change);
|
||||
this.breadcrumbService.setup(chrome.setBreadcrumbs);
|
||||
|
|
|
@ -7,7 +7,12 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { AnalyticsServiceStart, I18nStart, ThemeServiceStart } from '@kbn/core/public';
|
||||
import {
|
||||
AnalyticsServiceStart,
|
||||
I18nStart,
|
||||
ThemeServiceStart,
|
||||
UserProfileService,
|
||||
} from '@kbn/core/public';
|
||||
|
||||
export interface ConfigSchema {
|
||||
deeplinks: {
|
||||
|
@ -19,4 +24,5 @@ export interface DevToolsStartServices {
|
|||
analytics: Pick<AnalyticsServiceStart, 'reportEvent'>;
|
||||
i18n: I18nStart;
|
||||
theme: Pick<ThemeServiceStart, 'theme$'>;
|
||||
userProfile: UserProfileService;
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ export class GuidedOnboardingPlugin
|
|||
application,
|
||||
notifications,
|
||||
}: {
|
||||
startServices: Pick<CoreStart, 'analytics' | 'i18n' | 'theme'>;
|
||||
startServices: Pick<CoreStart, 'analytics' | 'i18n' | 'theme' | 'userProfile'>;
|
||||
targetDomElement: HTMLElement;
|
||||
api: ApiService;
|
||||
application: ApplicationStart;
|
||||
|
|
|
@ -116,7 +116,7 @@ export const ManagementApp = ({ dependencies, history, appBasePath }: Management
|
|||
};
|
||||
|
||||
return (
|
||||
<KibanaRenderContextProvider i18n={coreStart.i18n} theme={coreStart.theme}>
|
||||
<KibanaRenderContextProvider {...coreStart}>
|
||||
<RedirectAppLinks coreStart={dependencies.coreStart}>
|
||||
<AppContextProvider value={contextDependencies}>
|
||||
<KibanaPageTemplate
|
||||
|
|
|
@ -23,7 +23,7 @@ import { init as initDocumentation } from './services/documentation_links';
|
|||
import { App } from './app';
|
||||
import { ccrStore } from './store';
|
||||
|
||||
type StartServices = Pick<CoreStart, 'analytics' | 'i18n' | 'theme'>;
|
||||
type StartServices = Pick<CoreStart, 'analytics' | 'i18n' | 'theme' | 'userProfile'>;
|
||||
|
||||
const AppWithExecutionContext = ({
|
||||
history,
|
||||
|
|
|
@ -47,8 +47,9 @@ export const IndexManagementAppContext: React.FC<IndexManagementAppContextProps>
|
|||
analytics,
|
||||
i18n,
|
||||
theme,
|
||||
userProfile,
|
||||
} = core;
|
||||
const startServices = { analytics, i18n, overlays, theme };
|
||||
const startServices = { analytics, i18n, overlays, theme, userProfile };
|
||||
const { services, setBreadcrumbs, uiSettings, settings, kibanaVersion } = dependencies;
|
||||
|
||||
// theme is required by the CodeEditor component used to edit runtime field Painless scripts.
|
||||
|
@ -61,6 +62,7 @@ export const IndexManagementAppContext: React.FC<IndexManagementAppContextProps>
|
|||
get: () => kibanaVersion,
|
||||
},
|
||||
theme,
|
||||
userProfile,
|
||||
});
|
||||
|
||||
const componentTemplateProviderValues = {
|
||||
|
@ -122,6 +124,7 @@ interface KibanaReactContextServices {
|
|||
get: () => SemVer;
|
||||
};
|
||||
theme: CoreStart['theme'];
|
||||
userProfile: CoreStart['userProfile'];
|
||||
}
|
||||
|
||||
// We override useKibana() from the react plugin to return a typed version for this app
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
I18nStart,
|
||||
OverlayStart,
|
||||
ThemeServiceStart,
|
||||
UserProfileService,
|
||||
} from '@kbn/core/public';
|
||||
import { CloudSetup } from '@kbn/cloud-plugin/public';
|
||||
import { ConsolePluginStart } from '@kbn/console-plugin/public';
|
||||
|
@ -24,6 +25,7 @@ export interface IndexManagementStartServices {
|
|||
i18n: I18nStart;
|
||||
overlays: OverlayStart;
|
||||
theme: Pick<ThemeServiceStart, 'theme$'>;
|
||||
userProfile: UserProfileService;
|
||||
}
|
||||
|
||||
export interface SetupDependencies {
|
||||
|
|
|
@ -53,7 +53,7 @@ export interface AppServices {
|
|||
config: Config;
|
||||
}
|
||||
|
||||
type StartServices = Pick<CoreStart, 'analytics' | 'i18n' | 'theme'>;
|
||||
type StartServices = Pick<CoreStart, 'analytics' | 'i18n' | 'theme' | 'userProfile'>;
|
||||
|
||||
export interface CoreServices extends StartServices {
|
||||
http: HttpSetup;
|
||||
|
|
|
@ -51,16 +51,7 @@ export class PainlessLabUIPlugin implements Plugin<void, void, PluginDependencie
|
|||
mount: async ({ element }) => {
|
||||
const [core] = await getStartServices();
|
||||
|
||||
const {
|
||||
notifications,
|
||||
docLinks,
|
||||
chrome,
|
||||
settings,
|
||||
analytics,
|
||||
i18n: i18nStart,
|
||||
theme,
|
||||
} = core;
|
||||
const startServices = { analytics, i18n: i18nStart, theme };
|
||||
const { notifications, docLinks, chrome, settings, ...startServices } = core;
|
||||
|
||||
const license = await firstValueFrom(licensing.license$);
|
||||
const licenseStatus = checkLicenseStatus(license);
|
||||
|
|
|
@ -8,7 +8,12 @@
|
|||
import { HomePublicPluginSetup } from '@kbn/home-plugin/public';
|
||||
import { DevToolsSetup } from '@kbn/dev-tools-plugin/public';
|
||||
import { LicensingPluginSetup } from '@kbn/licensing-plugin/public';
|
||||
import { AnalyticsServiceStart, I18nStart, ThemeServiceStart } from '@kbn/core/public';
|
||||
import {
|
||||
AnalyticsServiceStart,
|
||||
I18nStart,
|
||||
ThemeServiceStart,
|
||||
UserProfileService,
|
||||
} from '@kbn/core/public';
|
||||
|
||||
export interface PluginDependencies {
|
||||
licensing: LicensingPluginSetup;
|
||||
|
@ -20,4 +25,5 @@ export interface PainlessLabStartServices {
|
|||
analytics: Pick<AnalyticsServiceStart, 'reportEvent'>;
|
||||
i18n: I18nStart;
|
||||
theme: Pick<ThemeServiceStart, 'theme$'>;
|
||||
userProfile: UserProfileService;
|
||||
}
|
||||
|
|
|
@ -17,5 +17,5 @@ export declare const renderApp: (
|
|||
canUseAPIKeyTrustModel: boolean;
|
||||
},
|
||||
history: ScopedHistory,
|
||||
startServices: Pick<CoreStart, 'analytics' | 'i18n' | 'theme'>
|
||||
startServices: Pick<CoreStart, 'analytics' | 'i18n' | 'theme' | 'userProfile'>
|
||||
) => ReturnType<RegisterManagementAppArgs['mount']>;
|
||||
|
|
|
@ -47,8 +47,7 @@ export class SearchProfilerUIPlugin implements Plugin<void, void, AppPublicPlugi
|
|||
enableRouting: false,
|
||||
mount: async (params) => {
|
||||
const [coreStart] = await getStartServices();
|
||||
const { notifications, analytics, i18n: i18nStart, theme } = coreStart;
|
||||
const startServices = { analytics, i18n: i18nStart, theme };
|
||||
const { notifications, ...startServices } = coreStart;
|
||||
|
||||
const { renderApp } = await import('./application');
|
||||
|
||||
|
|
|
@ -9,12 +9,18 @@ import { HomePublicPluginSetup } from '@kbn/home-plugin/public';
|
|||
import { DevToolsSetup } from '@kbn/dev-tools-plugin/public';
|
||||
import { SharePluginSetup } from '@kbn/share-plugin/public';
|
||||
import { LicensingPluginSetup } from '@kbn/licensing-plugin/public';
|
||||
import { AnalyticsServiceStart, I18nStart, ThemeServiceStart } from '@kbn/core/public';
|
||||
import {
|
||||
AnalyticsServiceStart,
|
||||
I18nStart,
|
||||
ThemeServiceStart,
|
||||
UserProfileService,
|
||||
} from '@kbn/core/public';
|
||||
|
||||
export interface SearchProfilerStartServices {
|
||||
analytics: Pick<AnalyticsServiceStart, 'reportEvent'>;
|
||||
i18n: I18nStart;
|
||||
theme: Pick<ThemeServiceStart, 'theme$'>;
|
||||
userProfile: UserProfileService;
|
||||
}
|
||||
|
||||
export interface AppPublicPluginDependencies {
|
||||
|
|
|
@ -48,6 +48,7 @@ export const mockContextValue: AppDeps = {
|
|||
toasts: notificationServiceMock.createSetupContract().toasts,
|
||||
i18n: coreStart.i18n,
|
||||
theme: coreStart.theme,
|
||||
userProfile: coreStart.userProfile,
|
||||
chartsTheme: {
|
||||
useChartsBaseTheme: jest.fn(),
|
||||
} as any,
|
||||
|
|
|
@ -16,6 +16,7 @@ import {
|
|||
ExecutionContextStart,
|
||||
ThemeServiceStart,
|
||||
I18nStart,
|
||||
UserProfileService,
|
||||
} from '@kbn/core/public';
|
||||
import type { SettingsStart } from '@kbn/core-ui-settings-browser';
|
||||
|
||||
|
@ -44,6 +45,7 @@ export interface AppDeps {
|
|||
uiSettings: IUiSettingsClient;
|
||||
i18n: I18nStart;
|
||||
theme: ThemeServiceStart;
|
||||
userProfile: UserProfileService;
|
||||
chartsTheme: ChartsPluginSetup['theme'];
|
||||
createTimeBuckets: () => any;
|
||||
licenseStatus$: Observable<LicenseStatus>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue