@backstage/core-app-api 0.1.10 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +58 -102
- package/dist/index.esm.js.map +1 -1
- package/package.json +7 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# @backstage/core-app-api
|
|
2
2
|
|
|
3
|
+
## 0.1.14
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @backstage/core-components@0.5.0
|
|
9
|
+
- @backstage/config@0.1.10
|
|
10
|
+
|
|
11
|
+
## 0.1.13
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 671015f132: Switch to using utilities from `@backstage/version-bridge'.
|
|
16
|
+
- bd1981d609: Allow users to specify their own AppThemeProvider
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- @backstage/core-components@0.4.2
|
|
19
|
+
- @backstage/core-plugin-api@0.1.8
|
|
20
|
+
|
|
21
|
+
## 0.1.12
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- 841666a19: Removed deprecated internal functions.
|
|
26
|
+
- Updated dependencies
|
|
27
|
+
- @backstage/core-components@0.4.1
|
|
28
|
+
- @backstage/config@0.1.9
|
|
29
|
+
- @backstage/core-plugin-api@0.1.7
|
|
30
|
+
|
|
31
|
+
## 0.1.11
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- Updated dependencies
|
|
36
|
+
- @backstage/core-components@0.4.0
|
|
37
|
+
|
|
3
38
|
## 0.1.10
|
|
4
39
|
|
|
5
40
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -393,6 +393,7 @@ declare type AppComponents = {
|
|
|
393
393
|
Progress: ComponentType<{}>;
|
|
394
394
|
Router: ComponentType<{}>;
|
|
395
395
|
ErrorBoundaryFallback: ComponentType<ErrorBoundaryFallbackProps>;
|
|
396
|
+
ThemeProvider: ComponentType<{}>;
|
|
396
397
|
/**
|
|
397
398
|
* An optional sign-in page that will be rendered instead of the AppRouter at startup.
|
|
398
399
|
*
|
package/dist/index.esm.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import React, { useContext,
|
|
1
|
+
import React, { useContext, Children, isValidElement, useMemo, useEffect, useState } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
+
import { createVersionedContext, createVersionedValueMap, getOrCreateGlobalSingleton } from '@backstage/version-bridge';
|
|
3
4
|
import OAuth2Icon from '@material-ui/icons/AcUnit';
|
|
4
5
|
import ObservableImpl from 'zen-observable';
|
|
5
|
-
import { SessionState, FeatureFlagState, useApi, featureFlagsApiRef, attachComponentData, appThemeApiRef, configApiRef, identityApiRef, createApiFactory, discoveryApiRef, alertApiRef, errorApiRef, storageApiRef, oauthRequestApiRef, googleAuthApiRef, microsoftAuthApiRef, githubAuthApiRef, oktaAuthApiRef, gitlabAuthApiRef, auth0AuthApiRef, oauth2ApiRef, samlAuthApiRef, oneloginAuthApiRef, oidcAuthApiRef, useApp, useElementFilter } from '@backstage/core-plugin-api';
|
|
6
|
+
import { SessionState, FeatureFlagState, getComponentData, useApi, featureFlagsApiRef, attachComponentData, appThemeApiRef, configApiRef, identityApiRef, createApiFactory, discoveryApiRef, alertApiRef, errorApiRef, storageApiRef, oauthRequestApiRef, googleAuthApiRef, microsoftAuthApiRef, githubAuthApiRef, oktaAuthApiRef, gitlabAuthApiRef, auth0AuthApiRef, oauth2ApiRef, samlAuthApiRef, oneloginAuthApiRef, oidcAuthApiRef, useApp, useElementFilter } from '@backstage/core-plugin-api';
|
|
6
7
|
import { ConfigReader } from '@backstage/config';
|
|
7
8
|
export { ConfigReader } from '@backstage/config';
|
|
8
9
|
import { ThemeProvider, CssBaseline, Button } from '@material-ui/core';
|
|
@@ -11,7 +12,7 @@ import { lightTheme, darkTheme } from '@backstage/theme';
|
|
|
11
12
|
import DarkIcon from '@material-ui/icons/Brightness2';
|
|
12
13
|
import LightIcon from '@material-ui/icons/WbSunny';
|
|
13
14
|
import { matchRoutes, generatePath, Routes, Route, BrowserRouter, useInRouterContext, MemoryRouter, useRoutes } from 'react-router-dom';
|
|
14
|
-
import {
|
|
15
|
+
import { useAsync, useObservable } from 'react-use';
|
|
15
16
|
import MuiApartmentIcon from '@material-ui/icons/Apartment';
|
|
16
17
|
import MuiBrokenImageIcon from '@material-ui/icons/BrokenImage';
|
|
17
18
|
import MuiCategoryIcon from '@material-ui/icons/Category';
|
|
@@ -44,38 +45,7 @@ class ApiAggregator {
|
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
if (typeof window !== "undefined" && window.Math === Math) {
|
|
49
|
-
return window;
|
|
50
|
-
}
|
|
51
|
-
if (typeof self !== "undefined" && self.Math === Math) {
|
|
52
|
-
return self;
|
|
53
|
-
}
|
|
54
|
-
return Function("return this")();
|
|
55
|
-
}
|
|
56
|
-
const globalObject = getGlobalObject();
|
|
57
|
-
const makeKey = (id) => `__@backstage/${id}__`;
|
|
58
|
-
function getOrCreateGlobalSingleton(id, supplier) {
|
|
59
|
-
const key = makeKey(id);
|
|
60
|
-
let value = globalObject[key];
|
|
61
|
-
if (value) {
|
|
62
|
-
return value;
|
|
63
|
-
}
|
|
64
|
-
value = supplier();
|
|
65
|
-
globalObject[key] = value;
|
|
66
|
-
return value;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function createVersionedValueMap(versions) {
|
|
70
|
-
Object.freeze(versions);
|
|
71
|
-
return {
|
|
72
|
-
atVersion(version) {
|
|
73
|
-
return versions[version];
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const ApiContext = getOrCreateGlobalSingleton("api-context", () => createContext(void 0));
|
|
48
|
+
const ApiContext = createVersionedContext("api-context");
|
|
79
49
|
const ApiProvider = ({
|
|
80
50
|
apis,
|
|
81
51
|
children
|
|
@@ -1677,23 +1647,6 @@ function routeElementDiscoverer(element) {
|
|
|
1677
1647
|
return void 0;
|
|
1678
1648
|
}
|
|
1679
1649
|
|
|
1680
|
-
const DATA_KEY = Symbol("backstage-component-data");
|
|
1681
|
-
const store = getOrCreateGlobalSingleton("component-data-store", () => new WeakMap());
|
|
1682
|
-
function getComponentData(node, type) {
|
|
1683
|
-
if (!node) {
|
|
1684
|
-
return void 0;
|
|
1685
|
-
}
|
|
1686
|
-
const component = node.type;
|
|
1687
|
-
if (!component) {
|
|
1688
|
-
return void 0;
|
|
1689
|
-
}
|
|
1690
|
-
const container = store.get(component) || component[DATA_KEY];
|
|
1691
|
-
if (!container) {
|
|
1692
|
-
return void 0;
|
|
1693
|
-
}
|
|
1694
|
-
return container.map.get(type);
|
|
1695
|
-
}
|
|
1696
|
-
|
|
1697
1650
|
const pluginCollector = createCollector(() => new Set(), (acc, node) => {
|
|
1698
1651
|
const plugin = getComponentData(node, "core.plugin");
|
|
1699
1652
|
if (plugin) {
|
|
@@ -1929,7 +1882,7 @@ class RouteResolver {
|
|
|
1929
1882
|
}
|
|
1930
1883
|
}
|
|
1931
1884
|
|
|
1932
|
-
const RoutingContext =
|
|
1885
|
+
const RoutingContext = createVersionedContext("routing-context");
|
|
1933
1886
|
const RoutingProvider = ({
|
|
1934
1887
|
routePaths,
|
|
1935
1888
|
routeParents,
|
|
@@ -1975,7 +1928,7 @@ function validateRoutes(routePaths, routeParents) {
|
|
|
1975
1928
|
}
|
|
1976
1929
|
}
|
|
1977
1930
|
|
|
1978
|
-
const AppContext =
|
|
1931
|
+
const AppContext = createVersionedContext("app-context");
|
|
1979
1932
|
const AppContextProvider = ({
|
|
1980
1933
|
appContext,
|
|
1981
1934
|
children
|
|
@@ -2036,52 +1989,6 @@ class AppIdentity {
|
|
|
2036
1989
|
}
|
|
2037
1990
|
}
|
|
2038
1991
|
|
|
2039
|
-
function resolveTheme(themeId, shouldPreferDark, themes) {
|
|
2040
|
-
if (themeId !== void 0) {
|
|
2041
|
-
const selectedTheme = themes.find((theme) => theme.id === themeId);
|
|
2042
|
-
if (selectedTheme) {
|
|
2043
|
-
return selectedTheme;
|
|
2044
|
-
}
|
|
2045
|
-
}
|
|
2046
|
-
if (shouldPreferDark) {
|
|
2047
|
-
const darkTheme = themes.find((theme) => theme.variant === "dark");
|
|
2048
|
-
if (darkTheme) {
|
|
2049
|
-
return darkTheme;
|
|
2050
|
-
}
|
|
2051
|
-
}
|
|
2052
|
-
const lightTheme = themes.find((theme) => theme.variant === "light");
|
|
2053
|
-
if (lightTheme) {
|
|
2054
|
-
return lightTheme;
|
|
2055
|
-
}
|
|
2056
|
-
return themes[0];
|
|
2057
|
-
}
|
|
2058
|
-
const useShouldPreferDarkTheme = () => {
|
|
2059
|
-
const mediaQuery = useMemo(() => window.matchMedia("(prefers-color-scheme: dark)"), []);
|
|
2060
|
-
const [shouldPreferDark, setPrefersDark] = useState(mediaQuery.matches);
|
|
2061
|
-
useEffect(() => {
|
|
2062
|
-
const listener = (event) => {
|
|
2063
|
-
setPrefersDark(event.matches);
|
|
2064
|
-
};
|
|
2065
|
-
mediaQuery.addListener(listener);
|
|
2066
|
-
return () => {
|
|
2067
|
-
mediaQuery.removeListener(listener);
|
|
2068
|
-
};
|
|
2069
|
-
}, [mediaQuery]);
|
|
2070
|
-
return shouldPreferDark;
|
|
2071
|
-
};
|
|
2072
|
-
function AppThemeProvider({children}) {
|
|
2073
|
-
const appThemeApi = useApi(appThemeApiRef);
|
|
2074
|
-
const themeId = useObservable(appThemeApi.activeThemeId$(), appThemeApi.getActiveThemeId());
|
|
2075
|
-
const shouldPreferDark = Boolean(window.matchMedia) ? useShouldPreferDarkTheme() : false;
|
|
2076
|
-
const appTheme = resolveTheme(themeId, shouldPreferDark, appThemeApi.getInstalledThemes());
|
|
2077
|
-
if (!appTheme) {
|
|
2078
|
-
throw new Error("App has no themes");
|
|
2079
|
-
}
|
|
2080
|
-
return /* @__PURE__ */ React.createElement(ThemeProvider, {
|
|
2081
|
-
theme: appTheme.theme
|
|
2082
|
-
}, /* @__PURE__ */ React.createElement(CssBaseline, null, children));
|
|
2083
|
-
}
|
|
2084
|
-
|
|
2085
1992
|
function generateBoundRoutes(bindRoutes) {
|
|
2086
1993
|
const result = new Map();
|
|
2087
1994
|
if (bindRoutes) {
|
|
@@ -2124,11 +2031,12 @@ function useConfigLoader(configLoader, components, appThemeApi) {
|
|
|
2124
2031
|
error: config.error
|
|
2125
2032
|
});
|
|
2126
2033
|
}
|
|
2034
|
+
const {ThemeProvider} = components;
|
|
2127
2035
|
if (noConfigNode) {
|
|
2128
2036
|
return {
|
|
2129
2037
|
node: /* @__PURE__ */ React.createElement(ApiProvider, {
|
|
2130
2038
|
apis: ApiRegistry.from([[appThemeApiRef, appThemeApi]])
|
|
2131
|
-
}, /* @__PURE__ */ React.createElement(
|
|
2039
|
+
}, /* @__PURE__ */ React.createElement(ThemeProvider, null, noConfigNode))
|
|
2132
2040
|
};
|
|
2133
2041
|
}
|
|
2134
2042
|
const configReader = ConfigReader.fromConfigs((_a = config.value) != null ? _a : []);
|
|
@@ -2221,11 +2129,12 @@ class PrivateAppImpl {
|
|
|
2221
2129
|
if ("node" in loadedConfig) {
|
|
2222
2130
|
return loadedConfig.node;
|
|
2223
2131
|
}
|
|
2132
|
+
const {ThemeProvider} = this.components;
|
|
2224
2133
|
return /* @__PURE__ */ React.createElement(ApiProvider, {
|
|
2225
2134
|
apis: this.getApiHolder()
|
|
2226
2135
|
}, /* @__PURE__ */ React.createElement(AppContextProvider, {
|
|
2227
2136
|
appContext
|
|
2228
|
-
}, /* @__PURE__ */ React.createElement(
|
|
2137
|
+
}, /* @__PURE__ */ React.createElement(ThemeProvider, null, /* @__PURE__ */ React.createElement(RoutingProvider, {
|
|
2229
2138
|
routePaths,
|
|
2230
2139
|
routeParents,
|
|
2231
2140
|
routeObjects,
|
|
@@ -2336,6 +2245,52 @@ class PrivateAppImpl {
|
|
|
2336
2245
|
}
|
|
2337
2246
|
}
|
|
2338
2247
|
|
|
2248
|
+
function resolveTheme(themeId, shouldPreferDark, themes) {
|
|
2249
|
+
if (themeId !== void 0) {
|
|
2250
|
+
const selectedTheme = themes.find((theme) => theme.id === themeId);
|
|
2251
|
+
if (selectedTheme) {
|
|
2252
|
+
return selectedTheme;
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
if (shouldPreferDark) {
|
|
2256
|
+
const darkTheme = themes.find((theme) => theme.variant === "dark");
|
|
2257
|
+
if (darkTheme) {
|
|
2258
|
+
return darkTheme;
|
|
2259
|
+
}
|
|
2260
|
+
}
|
|
2261
|
+
const lightTheme = themes.find((theme) => theme.variant === "light");
|
|
2262
|
+
if (lightTheme) {
|
|
2263
|
+
return lightTheme;
|
|
2264
|
+
}
|
|
2265
|
+
return themes[0];
|
|
2266
|
+
}
|
|
2267
|
+
const useShouldPreferDarkTheme = () => {
|
|
2268
|
+
const mediaQuery = useMemo(() => window.matchMedia("(prefers-color-scheme: dark)"), []);
|
|
2269
|
+
const [shouldPreferDark, setPrefersDark] = useState(mediaQuery.matches);
|
|
2270
|
+
useEffect(() => {
|
|
2271
|
+
const listener = (event) => {
|
|
2272
|
+
setPrefersDark(event.matches);
|
|
2273
|
+
};
|
|
2274
|
+
mediaQuery.addListener(listener);
|
|
2275
|
+
return () => {
|
|
2276
|
+
mediaQuery.removeListener(listener);
|
|
2277
|
+
};
|
|
2278
|
+
}, [mediaQuery]);
|
|
2279
|
+
return shouldPreferDark;
|
|
2280
|
+
};
|
|
2281
|
+
function AppThemeProvider({children}) {
|
|
2282
|
+
const appThemeApi = useApi(appThemeApiRef);
|
|
2283
|
+
const themeId = useObservable(appThemeApi.activeThemeId$(), appThemeApi.getActiveThemeId());
|
|
2284
|
+
const shouldPreferDark = Boolean(window.matchMedia) ? useShouldPreferDarkTheme() : false;
|
|
2285
|
+
const appTheme = resolveTheme(themeId, shouldPreferDark, appThemeApi.getInstalledThemes());
|
|
2286
|
+
if (!appTheme) {
|
|
2287
|
+
throw new Error("App has no themes");
|
|
2288
|
+
}
|
|
2289
|
+
return /* @__PURE__ */ React.createElement(ThemeProvider, {
|
|
2290
|
+
theme: appTheme.theme
|
|
2291
|
+
}, /* @__PURE__ */ React.createElement(CssBaseline, null, children));
|
|
2292
|
+
}
|
|
2293
|
+
|
|
2339
2294
|
const defaultApis = [
|
|
2340
2295
|
createApiFactory({
|
|
2341
2296
|
api: discoveryApiRef,
|
|
@@ -2592,6 +2547,7 @@ function createApp(options) {
|
|
|
2592
2547
|
Progress,
|
|
2593
2548
|
Router: BrowserRouter,
|
|
2594
2549
|
ErrorBoundaryFallback: DefaultErrorBoundaryFallback,
|
|
2550
|
+
ThemeProvider: AppThemeProvider,
|
|
2595
2551
|
...options == null ? void 0 : options.components
|
|
2596
2552
|
};
|
|
2597
2553
|
const themes = (_c = options == null ? void 0 : options.themes) != null ? _c : [
|