@backstage/plugin-app 0.4.1-next.2 → 0.4.2
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 +66 -0
- package/dist/apis/PluginHeaderActionsApi/DefaultPluginHeaderActionsApi.esm.js +8 -1
- package/dist/apis/PluginHeaderActionsApi/DefaultPluginHeaderActionsApi.esm.js.map +1 -1
- package/dist/apis/PluginWrapperApi/DefaultPluginWrapperApi.esm.js +134 -15
- package/dist/apis/PluginWrapperApi/DefaultPluginWrapperApi.esm.js.map +1 -1
- package/dist/apis/ToastApiForwarder.esm.js +94 -0
- package/dist/apis/ToastApiForwarder.esm.js.map +1 -0
- package/dist/apis/toastApiForwarderRef.esm.js +8 -0
- package/dist/apis/toastApiForwarderRef.esm.js.map +1 -0
- package/dist/components/Toast/Toast.esm.js +156 -0
- package/dist/components/Toast/Toast.esm.js.map +1 -0
- package/dist/components/Toast/Toast.module.css.esm.js +8 -0
- package/dist/components/Toast/Toast.module.css.esm.js.map +1 -0
- package/dist/components/Toast/ToastContainer.esm.js +90 -0
- package/dist/components/Toast/ToastContainer.esm.js.map +1 -0
- package/dist/components/Toast/ToastDisplay.esm.js +51 -0
- package/dist/components/Toast/ToastDisplay.esm.js.map +1 -0
- package/dist/defaultApis.esm.js +19 -1
- package/dist/defaultApis.esm.js.map +1 -1
- package/dist/extensions/AppNav.esm.js +35 -6
- package/dist/extensions/AppNav.esm.js.map +1 -1
- package/dist/extensions/AppRoot.esm.js +40 -34
- package/dist/extensions/AppRoot.esm.js.map +1 -1
- package/dist/extensions/IconsApi.esm.js.map +1 -1
- package/dist/extensions/PluginWrapperApi.esm.js +1 -2
- package/dist/extensions/PluginWrapperApi.esm.js.map +1 -1
- package/dist/extensions/components.esm.js +30 -18
- package/dist/extensions/components.esm.js.map +1 -1
- package/dist/extensions/elements.esm.js +4 -2
- package/dist/extensions/elements.esm.js.map +1 -1
- package/dist/hooks/useInvertedThemeMode.esm.js +41 -0
- package/dist/hooks/useInvertedThemeMode.esm.js.map +1 -0
- package/dist/index.d.ts +20 -6
- package/dist/node_modules_dist/style-inject/dist/style-inject.es.esm.js +29 -0
- package/dist/node_modules_dist/style-inject/dist/style-inject.es.esm.js.map +1 -0
- package/dist/packages/core-app-api/src/apis/implementations/AlertApi/AlertApiForwarder.esm.js +7 -0
- package/dist/packages/core-app-api/src/apis/implementations/AlertApi/AlertApiForwarder.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/auth/saml/types.esm.js +1 -1
- package/dist/packages/core-app-api/src/apis/implementations/auth/saml/types.esm.js.map +1 -1
- package/dist/packages/core-app-api/src/app/AppRouter.esm.js +11 -10
- package/dist/packages/core-app-api/src/app/AppRouter.esm.js.map +1 -1
- package/dist/packages/frontend-app-api/src/apis/implementations/IconsApi/DefaultIconsApi.esm.js +39 -3
- package/dist/packages/frontend-app-api/src/apis/implementations/IconsApi/DefaultIconsApi.esm.js.map +1 -1
- package/dist/packages/frontend-internal/src/wiring/InternalExtensionDefinition.esm.js.map +1 -1
- package/dist/packages/frontend-internal/src/wiring/InternalFrontendPlugin.esm.js.map +1 -1
- package/dist/packages/ui/src/hooks/useBg.esm.js +19 -0
- package/dist/packages/ui/src/hooks/useBg.esm.js.map +1 -0
- package/dist/packages/ui/src/hooks/useBreakpoint.esm.js +17 -0
- package/dist/packages/ui/src/hooks/useBreakpoint.esm.js.map +1 -0
- package/dist/packages/ui/src/hooks/useDefinition/helpers.esm.js +4 -0
- package/dist/packages/ui/src/hooks/useDefinition/helpers.esm.js.map +1 -0
- package/dist/plugins/app/package.json.esm.js +9 -2
- package/dist/plugins/app/package.json.esm.js.map +1 -1
- package/package.json +24 -17
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppRoot.esm.js","sources":["../../src/extensions/AppRoot.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ComponentType,\n PropsWithChildren,\n ReactNode,\n useState,\n JSX,\n} from 'react';\nimport {\n coreExtensionData,\n discoveryApiRef,\n fetchApiRef,\n errorApiRef,\n createExtension,\n createExtensionInput,\n routeResolutionApiRef,\n useAnalytics,\n} from '@backstage/frontend-plugin-api';\nimport {\n AppRootWrapperBlueprint,\n RouterBlueprint,\n SignInPageBlueprint,\n} from '@backstage/plugin-app-react';\nimport { BUIProvider } from '@backstage/ui';\nimport {\n DiscoveryApi,\n ErrorApi,\n FetchApi,\n IdentityApi,\n ProfileInfo,\n SignInPageProps,\n configApiRef,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { isProtectedApp } from '../../../../packages/core-app-api/src/app/isProtectedApp';\nimport { BrowserRouter } from 'react-router-dom';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { RouteTracker } from '../../../../packages/frontend-app-api/src/routing/RouteTracker';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { getBasePath } from '../../../../packages/frontend-app-api/src/routing/getBasePath';\n\nexport const AppRoot = createExtension({\n name: 'root',\n attachTo: { id: 'app', input: 'root' },\n inputs: {\n router: createExtensionInput([RouterBlueprint.dataRefs.component], {\n singleton: true,\n optional: true,\n internal: true,\n }),\n signInPage: createExtensionInput([SignInPageBlueprint.dataRefs.component], {\n singleton: true,\n optional: true,\n internal: true,\n }),\n children: createExtensionInput([coreExtensionData.reactElement], {\n singleton: true,\n }),\n elements: createExtensionInput([coreExtensionData.reactElement]),\n wrappers: createExtensionInput(\n [AppRootWrapperBlueprint.dataRefs.component],\n {\n internal: true,\n },\n ),\n },\n output: [coreExtensionData.reactElement],\n factory({ inputs, apis }) {\n if (isProtectedApp()) {\n const identityApi = apis.get(identityApiRef);\n if (!identityApi) {\n throw new Error('App requires an Identity API implementation');\n }\n const appIdentityProxy = toAppIdentityProxy(identityApi);\n const discoveryApi = apis.get(discoveryApiRef);\n const errorApi = apis.get(errorApiRef);\n const fetchApi = apis.get(fetchApiRef);\n if (!discoveryApi || !errorApi || !fetchApi) {\n throw new Error(\n 'App is running in protected mode but missing required APIs',\n );\n }\n appIdentityProxy.enableCookieAuth({\n discoveryApi,\n errorApi,\n fetchApi,\n });\n }\n\n let content: ReactNode = inputs.children.get(\n coreExtensionData.reactElement,\n );\n\n for (const wrapper of inputs.wrappers) {\n const Component = wrapper.get(AppRootWrapperBlueprint.dataRefs.component);\n if (Component) {\n content = <Component>{content}</Component>;\n }\n }\n\n return [\n coreExtensionData.reactElement(\n <BUIProvider useAnalytics={useAnalytics}>\n <AppRouter\n SignInPageComponent={inputs.signInPage?.get(\n SignInPageBlueprint.dataRefs.component,\n )}\n RouterComponent={inputs.router?.get(\n RouterBlueprint.dataRefs.component,\n )}\n extraElements={inputs.elements?.map(el =>\n el.get(coreExtensionData.reactElement),\n )}\n >\n {content}\n </AppRouter>\n </BUIProvider>,\n ),\n ];\n },\n});\n\n// This wraps the sign-in page and waits for sign-in to be completed before rendering the app\nfunction SignInPageWrapper({\n component: Component,\n appIdentityProxy,\n children,\n}: {\n component: ComponentType<SignInPageProps>;\n appIdentityProxy: AppIdentityProxy;\n children: ReactNode;\n}) {\n const [identityApi, setIdentityApi] = useState<IdentityApi>();\n const configApi = useApi(configApiRef);\n const basePath = getBasePath(configApi);\n\n if (!identityApi) {\n return <Component onSignInSuccess={setIdentityApi} />;\n }\n\n appIdentityProxy.setTarget(identityApi, {\n signOutTargetUrl: basePath || '/',\n });\n return <>{children}</>;\n}\n\ntype AppIdentityProxy = IdentityApi & {\n enableCookieAuth(ctx: {\n errorApi: ErrorApi;\n fetchApi: FetchApi;\n discoveryApi: DiscoveryApi;\n }): void;\n setTarget(\n impl: IdentityApi & /* backwards compat stuff */ {\n getUserId?(): string;\n getIdToken?(): Promise<string | undefined>;\n getProfile?(): ProfileInfo;\n },\n options: { signOutTargetUrl: string },\n ): void;\n};\n\nfunction toAppIdentityProxy(identityApi: IdentityApi): AppIdentityProxy {\n if (!('enableCookieAuth' in identityApi)) {\n throw new Error('Unexpected Identity API implementation');\n }\n return identityApi as AppIdentityProxy;\n}\n\ntype RouteResolverProxy = {\n getRouteObjects(): any[];\n};\n\n/**\n * Props for the {@link AppRouter} component.\n * @public\n */\nexport interface AppRouterProps {\n children?: ReactNode;\n SignInPageComponent?: ComponentType<SignInPageProps>;\n RouterComponent?: (props: { children: ReactNode }) => JSX.Element | null;\n extraElements?: Array<JSX.Element>;\n}\n\nfunction DefaultRouter(props: PropsWithChildren<{}>) {\n const configApi = useApi(configApiRef);\n const basePath = getBasePath(configApi);\n return (\n <BrowserRouter\n basename={basePath}\n future={{\n v7_relativeSplatPath: false,\n v7_startTransition: false,\n }}\n >\n {props.children}\n </BrowserRouter>\n );\n}\n\n/**\n * App router and sign-in page wrapper.\n *\n * @remarks\n *\n * The AppRouter provides the routing context and renders the sign-in page.\n * Until the user has successfully signed in, this component will render\n * the sign-in page. Once the user has signed-in, it will instead render\n * the app, while providing routing and route tracking for the app.\n */\nexport function AppRouter(props: AppRouterProps) {\n const {\n children,\n SignInPageComponent,\n RouterComponent = DefaultRouter,\n extraElements = [],\n } = props;\n\n const configApi = useApi(configApiRef);\n const appIdentityProxy = toAppIdentityProxy(useApi(identityApiRef));\n const routeResolutionsApi = useApi(routeResolutionApiRef);\n const basePath = getBasePath(configApi);\n\n // TODO: Private access for now, probably replace with path -> node lookup method on the API\n if (!('getRouteObjects' in routeResolutionsApi)) {\n throw new Error('Unexpected route resolution API implementation');\n }\n const routeObjects = (\n routeResolutionsApi as RouteResolverProxy\n ).getRouteObjects();\n\n // If the app hasn't configured a sign-in page, we just continue as guest.\n if (!SignInPageComponent) {\n appIdentityProxy.setTarget(\n {\n getUserId: () => 'guest',\n getIdToken: async () => undefined,\n getProfile: () => ({\n email: 'guest@example.com',\n displayName: 'Guest',\n }),\n getProfileInfo: async () => ({\n email: 'guest@example.com',\n displayName: 'Guest',\n }),\n getBackstageIdentity: async () => ({\n type: 'user',\n userEntityRef: 'user:default/guest',\n ownershipEntityRefs: ['user:default/guest'],\n }),\n getCredentials: async () => ({}),\n signOut: async () => {},\n },\n { signOutTargetUrl: basePath || '/' },\n );\n\n return (\n <RouterComponent>\n {...extraElements}\n <RouteTracker routeObjects={routeObjects} />\n {children}\n </RouterComponent>\n );\n }\n\n return (\n <RouterComponent>\n {...extraElements}\n <RouteTracker routeObjects={routeObjects} />\n <SignInPageWrapper\n component={SignInPageComponent}\n appIdentityProxy={appIdentityProxy}\n >\n {children}\n </SignInPageWrapper>\n </RouterComponent>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AppRoot.esm.js","sources":["../../src/extensions/AppRoot.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ComponentType,\n PropsWithChildren,\n ReactNode,\n useState,\n JSX,\n} from 'react';\nimport {\n ExtensionBoundary,\n coreExtensionData,\n discoveryApiRef,\n fetchApiRef,\n errorApiRef,\n createExtension,\n createExtensionInput,\n routeResolutionApiRef,\n pluginWrapperApiRef,\n useAnalytics,\n} from '@backstage/frontend-plugin-api';\nimport {\n AppRootWrapperBlueprint,\n RouterBlueprint,\n SignInPageBlueprint,\n} from '@backstage/plugin-app-react';\nimport { BUIProvider } from '@backstage/ui';\nimport {\n DiscoveryApi,\n ErrorApi,\n FetchApi,\n IdentityApi,\n ProfileInfo,\n SignInPageProps,\n configApiRef,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { isProtectedApp } from '../../../../packages/core-app-api/src/app/isProtectedApp';\nimport { BrowserRouter } from 'react-router-dom';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { RouteTracker } from '../../../../packages/frontend-app-api/src/routing/RouteTracker';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { getBasePath } from '../../../../packages/frontend-app-api/src/routing/getBasePath';\n\nexport const AppRoot = createExtension({\n name: 'root',\n attachTo: { id: 'app', input: 'root' },\n inputs: {\n router: createExtensionInput([RouterBlueprint.dataRefs.component], {\n singleton: true,\n optional: true,\n internal: true,\n }),\n signInPage: createExtensionInput([SignInPageBlueprint.dataRefs.component], {\n singleton: true,\n optional: true,\n internal: true,\n }),\n children: createExtensionInput([coreExtensionData.reactElement], {\n singleton: true,\n optional: true,\n }),\n elements: createExtensionInput([coreExtensionData.reactElement]),\n wrappers: createExtensionInput(\n [AppRootWrapperBlueprint.dataRefs.component],\n {\n internal: true,\n },\n ),\n },\n output: [coreExtensionData.reactElement],\n factory({ inputs, apis, node }) {\n if (isProtectedApp()) {\n const identityApi = apis.get(identityApiRef);\n if (!identityApi) {\n throw new Error('App requires an Identity API implementation');\n }\n const appIdentityProxy = toAppIdentityProxy(identityApi);\n const discoveryApi = apis.get(discoveryApiRef);\n const errorApi = apis.get(errorApiRef);\n const fetchApi = apis.get(fetchApiRef);\n if (!discoveryApi || !errorApi || !fetchApi) {\n throw new Error(\n 'App is running in protected mode but missing required APIs',\n );\n }\n appIdentityProxy.enableCookieAuth({\n discoveryApi,\n errorApi,\n fetchApi,\n });\n }\n\n let content = inputs.children?.get(coreExtensionData.reactElement);\n\n for (const wrapper of inputs.wrappers) {\n const Component = wrapper.get(AppRootWrapperBlueprint.dataRefs.component);\n if (Component) {\n content = <Component>{content}</Component>;\n }\n }\n\n const pluginWrapperApi = apis.get(pluginWrapperApiRef);\n const RootWrapper = pluginWrapperApi?.getRootWrapper();\n if (RootWrapper) {\n content = <RootWrapper>{content}</RootWrapper>;\n }\n\n return [\n coreExtensionData.reactElement(\n <ExtensionBoundary node={node}>\n <AppRouter\n SignInPageComponent={inputs.signInPage?.get(\n SignInPageBlueprint.dataRefs.component,\n )}\n RouterComponent={inputs.router?.get(\n RouterBlueprint.dataRefs.component,\n )}\n extraElements={inputs.elements?.map(el =>\n el.get(coreExtensionData.reactElement),\n )}\n >\n {content}\n </AppRouter>\n </ExtensionBoundary>,\n ),\n ];\n },\n});\n\n// This wraps the sign-in page and waits for sign-in to be completed before rendering the app\nfunction SignInPageWrapper({\n component: Component,\n appIdentityProxy,\n children,\n}: {\n component: ComponentType<SignInPageProps>;\n appIdentityProxy: AppIdentityProxy;\n children: ReactNode;\n}) {\n const [identityApi, setIdentityApi] = useState<IdentityApi>();\n const configApi = useApi(configApiRef);\n const basePath = getBasePath(configApi);\n\n if (!identityApi) {\n return <Component onSignInSuccess={setIdentityApi} />;\n }\n\n appIdentityProxy.setTarget(identityApi, {\n signOutTargetUrl: basePath || '/',\n });\n return <>{children}</>;\n}\n\ntype AppIdentityProxy = IdentityApi & {\n enableCookieAuth(ctx: {\n errorApi: ErrorApi;\n fetchApi: FetchApi;\n discoveryApi: DiscoveryApi;\n }): void;\n setTarget(\n impl: IdentityApi & /* backwards compat stuff */ {\n getUserId?(): string;\n getIdToken?(): Promise<string | undefined>;\n getProfile?(): ProfileInfo;\n },\n options: { signOutTargetUrl: string },\n ): void;\n};\n\nfunction toAppIdentityProxy(identityApi: IdentityApi): AppIdentityProxy {\n if (!('enableCookieAuth' in identityApi)) {\n throw new Error('Unexpected Identity API implementation');\n }\n return identityApi as AppIdentityProxy;\n}\n\ntype RouteResolverProxy = {\n getRouteObjects(): any[];\n};\n\n/**\n * Props for the {@link AppRouter} component.\n * @public\n */\nexport interface AppRouterProps {\n children?: ReactNode;\n SignInPageComponent?: ComponentType<SignInPageProps>;\n RouterComponent?: (props: { children: ReactNode }) => JSX.Element | null;\n extraElements?: Array<JSX.Element>;\n}\n\nfunction DefaultRouter(props: PropsWithChildren<{}>) {\n const configApi = useApi(configApiRef);\n const basePath = getBasePath(configApi);\n return (\n <BrowserRouter\n basename={basePath}\n future={{\n v7_relativeSplatPath: false,\n v7_startTransition: false,\n }}\n >\n {props.children}\n </BrowserRouter>\n );\n}\n\n/**\n * App router and sign-in page wrapper.\n *\n * @remarks\n *\n * The AppRouter provides the routing context and renders the sign-in page.\n * Until the user has successfully signed in, this component will render\n * the sign-in page. Once the user has signed-in, it will instead render\n * the app, while providing routing and route tracking for the app.\n */\nexport function AppRouter(props: AppRouterProps) {\n const {\n children,\n SignInPageComponent,\n RouterComponent = DefaultRouter,\n extraElements = [],\n } = props;\n\n const configApi = useApi(configApiRef);\n const appIdentityProxy = toAppIdentityProxy(useApi(identityApiRef));\n const routeResolutionsApi = useApi(routeResolutionApiRef);\n const basePath = getBasePath(configApi);\n\n // TODO: Private access for now, probably replace with path -> node lookup method on the API\n if (!('getRouteObjects' in routeResolutionsApi)) {\n throw new Error('Unexpected route resolution API implementation');\n }\n const routeObjects = (\n routeResolutionsApi as RouteResolverProxy\n ).getRouteObjects();\n\n // If the app hasn't configured a sign-in page, we just continue as guest.\n if (!SignInPageComponent) {\n if (!isProtectedApp()) {\n appIdentityProxy.setTarget(\n {\n getUserId: () => 'guest',\n getIdToken: async () => undefined,\n getProfile: () => ({\n email: 'guest@example.com',\n displayName: 'Guest',\n }),\n getProfileInfo: async () => ({\n email: 'guest@example.com',\n displayName: 'Guest',\n }),\n getBackstageIdentity: async () => ({\n type: 'user',\n userEntityRef: 'user:default/guest',\n ownershipEntityRefs: ['user:default/guest'],\n }),\n getCredentials: async () => ({}),\n signOut: async () => {},\n },\n { signOutTargetUrl: basePath || '/' },\n );\n }\n\n return (\n <RouterComponent>\n <BUIProvider useAnalytics={useAnalytics}>\n {...extraElements}\n <RouteTracker routeObjects={routeObjects} />\n {children}\n </BUIProvider>\n </RouterComponent>\n );\n }\n\n return (\n <RouterComponent>\n <BUIProvider useAnalytics={useAnalytics}>\n {...extraElements}\n <RouteTracker routeObjects={routeObjects} />\n <SignInPageWrapper\n component={SignInPageComponent}\n appIdentityProxy={appIdentityProxy}\n >\n {children}\n </SignInPageWrapper>\n </BUIProvider>\n </RouterComponent>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;AA4DO,MAAM,UAAU,eAAA,CAAgB;AAAA,EACrC,IAAA,EAAM,MAAA;AAAA,EACN,QAAA,EAAU,EAAE,EAAA,EAAI,KAAA,EAAO,OAAO,MAAA,EAAO;AAAA,EACrC,MAAA,EAAQ;AAAA,IACN,QAAQ,oBAAA,CAAqB,CAAC,eAAA,CAAgB,QAAA,CAAS,SAAS,CAAA,EAAG;AAAA,MACjE,SAAA,EAAW,IAAA;AAAA,MACX,QAAA,EAAU,IAAA;AAAA,MACV,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,IACD,YAAY,oBAAA,CAAqB,CAAC,mBAAA,CAAoB,QAAA,CAAS,SAAS,CAAA,EAAG;AAAA,MACzE,SAAA,EAAW,IAAA;AAAA,MACX,QAAA,EAAU,IAAA;AAAA,MACV,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,IACD,QAAA,EAAU,oBAAA,CAAqB,CAAC,iBAAA,CAAkB,YAAY,CAAA,EAAG;AAAA,MAC/D,SAAA,EAAW,IAAA;AAAA,MACX,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,IACD,QAAA,EAAU,oBAAA,CAAqB,CAAC,iBAAA,CAAkB,YAAY,CAAC,CAAA;AAAA,IAC/D,QAAA,EAAU,oBAAA;AAAA,MACR,CAAC,uBAAA,CAAwB,QAAA,CAAS,SAAS,CAAA;AAAA,MAC3C;AAAA,QACE,QAAA,EAAU;AAAA;AACZ;AACF,GACF;AAAA,EACA,MAAA,EAAQ,CAAC,iBAAA,CAAkB,YAAY,CAAA;AAAA,EACvC,OAAA,CAAQ,EAAE,MAAA,EAAQ,IAAA,EAAM,MAAK,EAAG;AAC9B,IAAA,IAAI,gBAAe,EAAG;AACpB,MAAA,MAAM,WAAA,GAAc,IAAA,CAAK,GAAA,CAAI,cAAc,CAAA;AAC3C,MAAA,IAAI,CAAC,WAAA,EAAa;AAChB,QAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAAA,MAC/D;AACA,MAAA,MAAM,gBAAA,GAAmB,mBAAmB,WAAW,CAAA;AACvD,MAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,eAAe,CAAA;AAC7C,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,WAAW,CAAA;AACrC,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,WAAW,CAAA;AACrC,MAAA,IAAI,CAAC,YAAA,IAAgB,CAAC,QAAA,IAAY,CAAC,QAAA,EAAU;AAC3C,QAAA,MAAM,IAAI,KAAA;AAAA,UACR;AAAA,SACF;AAAA,MACF;AACA,MAAA,gBAAA,CAAiB,gBAAA,CAAiB;AAAA,QAChC,YAAA;AAAA,QACA,QAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,OAAA,GAAU,MAAA,CAAO,QAAA,EAAU,GAAA,CAAI,kBAAkB,YAAY,CAAA;AAEjE,IAAA,KAAA,MAAW,OAAA,IAAW,OAAO,QAAA,EAAU;AACrC,MAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,GAAA,CAAI,uBAAA,CAAwB,SAAS,SAAS,CAAA;AACxE,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,OAAA,mBAAU,GAAA,CAAC,aAAW,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,MAChC;AAAA,IACF;AAEA,IAAA,MAAM,gBAAA,GAAmB,IAAA,CAAK,GAAA,CAAI,mBAAmB,CAAA;AACrD,IAAA,MAAM,WAAA,GAAc,kBAAkB,cAAA,EAAe;AACrD,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,OAAA,mBAAU,GAAA,CAAC,eAAa,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,IAClC;AAEA,IAAA,OAAO;AAAA,MACL,iBAAA,CAAkB,YAAA;AAAA,wBAChB,GAAA,CAAC,qBAAkB,IAAA,EACjB,QAAA,kBAAA,GAAA;AAAA,UAAC,SAAA;AAAA,UAAA;AAAA,YACC,mBAAA,EAAqB,OAAO,UAAA,EAAY,GAAA;AAAA,cACtC,oBAAoB,QAAA,CAAS;AAAA,aAC/B;AAAA,YACA,eAAA,EAAiB,OAAO,MAAA,EAAQ,GAAA;AAAA,cAC9B,gBAAgB,QAAA,CAAS;AAAA,aAC3B;AAAA,YACA,aAAA,EAAe,OAAO,QAAA,EAAU,GAAA;AAAA,cAAI,CAAA,EAAA,KAClC,EAAA,CAAG,GAAA,CAAI,iBAAA,CAAkB,YAAY;AAAA,aACvC;AAAA,YAEC,QAAA,EAAA;AAAA;AAAA,SACH,EACF;AAAA;AACF,KACF;AAAA,EACF;AACF,CAAC;AAGD,SAAS,iBAAA,CAAkB;AAAA,EACzB,SAAA,EAAW,SAAA;AAAA,EACX,gBAAA;AAAA,EACA;AACF,CAAA,EAIG;AACD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,QAAA,EAAsB;AAC5D,EAAA,MAAM,SAAA,GAAY,OAAO,YAAY,CAAA;AACrC,EAAA,MAAM,QAAA,GAAW,YAAY,SAAS,CAAA;AAEtC,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,uBAAO,GAAA,CAAC,SAAA,EAAA,EAAU,eAAA,EAAiB,cAAA,EAAgB,CAAA;AAAA,EACrD;AAEA,EAAA,gBAAA,CAAiB,UAAU,WAAA,EAAa;AAAA,IACtC,kBAAkB,QAAA,IAAY;AAAA,GAC/B,CAAA;AACD,EAAA,uCAAU,QAAA,EAAS,CAAA;AACrB;AAkBA,SAAS,mBAAmB,WAAA,EAA4C;AACtE,EAAA,IAAI,EAAE,sBAAsB,WAAA,CAAA,EAAc;AACxC,IAAA,MAAM,IAAI,MAAM,wCAAwC,CAAA;AAAA,EAC1D;AACA,EAAA,OAAO,WAAA;AACT;AAiBA,SAAS,cAAc,KAAA,EAA8B;AACnD,EAAA,MAAM,SAAA,GAAY,OAAO,YAAY,CAAA;AACrC,EAAA,MAAM,QAAA,GAAW,YAAY,SAAS,CAAA;AACtC,EAAA,uBACE,GAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,QAAA,EAAU,QAAA;AAAA,MACV,MAAA,EAAQ;AAAA,QACN,oBAAA,EAAsB,KAAA;AAAA,QACtB,kBAAA,EAAoB;AAAA,OACtB;AAAA,MAEC,QAAA,EAAA,KAAA,CAAM;AAAA;AAAA,GACT;AAEJ;AAYO,SAAS,UAAU,KAAA,EAAuB;AAC/C,EAAA,MAAM;AAAA,IACJ,QAAA;AAAA,IACA,mBAAA;AAAA,IACA,eAAA,GAAkB,aAAA;AAAA,IAClB,gBAAgB;AAAC,GACnB,GAAI,KAAA;AAEJ,EAAA,MAAM,SAAA,GAAY,OAAO,YAAY,CAAA;AACrC,EAAA,MAAM,gBAAA,GAAmB,kBAAA,CAAmB,MAAA,CAAO,cAAc,CAAC,CAAA;AAClE,EAAA,MAAM,mBAAA,GAAsB,OAAO,qBAAqB,CAAA;AACxD,EAAA,MAAM,QAAA,GAAW,YAAY,SAAS,CAAA;AAGtC,EAAA,IAAI,EAAE,qBAAqB,mBAAA,CAAA,EAAsB;AAC/C,IAAA,MAAM,IAAI,MAAM,gDAAgD,CAAA;AAAA,EAClE;AACA,EAAA,MAAM,YAAA,GACJ,oBACA,eAAA,EAAgB;AAGlB,EAAA,IAAI,CAAC,mBAAA,EAAqB;AACxB,IAAA,IAAI,CAAC,gBAAe,EAAG;AACrB,MAAA,gBAAA,CAAiB,SAAA;AAAA,QACf;AAAA,UACE,WAAW,MAAM,OAAA;AAAA,UACjB,YAAY,YAAY,MAAA;AAAA,UACxB,YAAY,OAAO;AAAA,YACjB,KAAA,EAAO,mBAAA;AAAA,YACP,WAAA,EAAa;AAAA,WACf,CAAA;AAAA,UACA,gBAAgB,aAAa;AAAA,YAC3B,KAAA,EAAO,mBAAA;AAAA,YACP,WAAA,EAAa;AAAA,WACf,CAAA;AAAA,UACA,sBAAsB,aAAa;AAAA,YACjC,IAAA,EAAM,MAAA;AAAA,YACN,aAAA,EAAe,oBAAA;AAAA,YACf,mBAAA,EAAqB,CAAC,oBAAoB;AAAA,WAC5C,CAAA;AAAA,UACA,cAAA,EAAgB,aAAa,EAAC,CAAA;AAAA,UAC9B,SAAS,YAAY;AAAA,UAAC;AAAA,SACxB;AAAA,QACA,EAAE,gBAAA,EAAkB,QAAA,IAAY,GAAA;AAAI,OACtC;AAAA,IACF;AAEA,IAAA,uBACE,GAAA,CAAC,eAAA,EAAA,EACC,QAAA,kBAAA,IAAA,CAAC,WAAA,EAAA,EAAY,YAAA,EACV,QAAA,EAAA;AAAA,MAAA,GAAG,aAAA;AAAA,sBACJ,GAAA,CAAC,gBAAa,YAAA,EAA4B,CAAA;AAAA,MACzC;AAAA,KAAA,EACH,CAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,uBACE,GAAA,CAAC,eAAA,EAAA,EACC,QAAA,kBAAA,IAAA,CAAC,WAAA,EAAA,EAAY,YAAA,EACV,QAAA,EAAA;AAAA,IAAA,GAAG,aAAA;AAAA,oBACJ,GAAA,CAAC,gBAAa,YAAA,EAA4B,CAAA;AAAA,oBAC1C,GAAA;AAAA,MAAC,iBAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,mBAAA;AAAA,QACX,gBAAA;AAAA,QAEC;AAAA;AAAA;AACH,GAAA,EACF,CAAA,EACF,CAAA;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconsApi.esm.js","sources":["../../src/extensions/IconsApi.
|
|
1
|
+
{"version":3,"file":"IconsApi.esm.js","sources":["../../src/extensions/IconsApi.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createExtensionInput,\n ApiBlueprint,\n iconsApiRef,\n} from '@backstage/frontend-plugin-api';\nimport { IconBundleBlueprint } from '@backstage/plugin-app-react';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { DefaultIconsApi } from '../../../../packages/frontend-app-api/src/apis/implementations/IconsApi';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { icons as defaultIcons } from '../../../../packages/app-defaults/src/defaults';\n\n/**\n * Contains the shareable icons installed into the app.\n */\nexport const IconsApi = ApiBlueprint.makeWithOverrides({\n name: 'icons',\n inputs: {\n icons: createExtensionInput([IconBundleBlueprint.dataRefs.icons], {\n replaces: [{ id: 'app', input: 'icons' }],\n internal: true,\n }),\n },\n factory: (originalFactory, { inputs }) => {\n return originalFactory(defineParams =>\n defineParams({\n api: iconsApiRef,\n deps: {},\n factory: () => {\n return new DefaultIconsApi(\n inputs.icons\n .map(i => i.get(IconBundleBlueprint.dataRefs.icons))\n .reduce((acc, bundle) => ({ ...acc, ...bundle }), defaultIcons),\n );\n },\n }),\n );\n },\n});\n"],"names":["defaultIcons"],"mappings":";;;;;;;;;;;;;AA8BO,MAAM,QAAA,GAAW,aAAa,iBAAA,CAAkB;AAAA,EACrD,IAAA,EAAM,OAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,OAAO,oBAAA,CAAqB,CAAC,mBAAA,CAAoB,QAAA,CAAS,KAAK,CAAA,EAAG;AAAA,MAChE,UAAU,CAAC,EAAE,IAAI,KAAA,EAAO,KAAA,EAAO,SAAS,CAAA;AAAA,MACxC,QAAA,EAAU;AAAA,KACX;AAAA,GACH;AAAA,EACA,OAAA,EAAS,CAAC,eAAA,EAAiB,EAAE,QAAO,KAAM;AACxC,IAAA,OAAO,eAAA;AAAA,MAAgB,kBACrB,YAAA,CAAa;AAAA,QACX,GAAA,EAAK,WAAA;AAAA,QACL,MAAM,EAAC;AAAA,QACP,SAAS,MAAM;AACb,UAAA,OAAO,IAAI,eAAA;AAAA,YACT,MAAA,CAAO,MACJ,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,GAAA,CAAI,mBAAA,CAAoB,SAAS,KAAK,CAAC,EAClD,MAAA,CAAO,CAAC,KAAK,MAAA,MAAY,EAAE,GAAG,GAAA,EAAK,GAAG,MAAA,EAAO,CAAA,EAAIA,KAAY;AAAA,WAClE;AAAA,QACF;AAAA,OACD;AAAA,KACH;AAAA,EACF;AACF,CAAC;;;;"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { pluginWrapperApiRef, PluginWrapperBlueprint } from '@backstage/frontend-plugin-api
|
|
2
|
-
import { ApiBlueprint, createExtensionInput } from '@backstage/frontend-plugin-api';
|
|
1
|
+
import { ApiBlueprint, createExtensionInput, pluginWrapperApiRef, PluginWrapperBlueprint } from '@backstage/frontend-plugin-api';
|
|
3
2
|
import { DefaultPluginWrapperApi } from '../apis/PluginWrapperApi/DefaultPluginWrapperApi.esm.js';
|
|
4
3
|
|
|
5
4
|
const PluginWrapperApi = ApiBlueprint.makeWithOverrides({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginWrapperApi.esm.js","sources":["../../src/extensions/PluginWrapperApi.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n PluginWrapperBlueprint,\n pluginWrapperApiRef,\n
|
|
1
|
+
{"version":3,"file":"PluginWrapperApi.esm.js","sources":["../../src/extensions/PluginWrapperApi.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n PluginWrapperBlueprint,\n pluginWrapperApiRef,\n createExtensionInput,\n ApiBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport { DefaultPluginWrapperApi } from '../apis/PluginWrapperApi';\n\n/**\n * Contains the plugin wrappers installed into the app.\n */\nexport const PluginWrapperApi = ApiBlueprint.makeWithOverrides({\n name: 'plugin-wrapper',\n inputs: {\n wrappers: createExtensionInput([PluginWrapperBlueprint.dataRefs.wrapper]),\n },\n factory: (originalFactory, { inputs }) => {\n return originalFactory(defineParams =>\n defineParams({\n api: pluginWrapperApiRef,\n deps: {},\n factory: () => {\n return DefaultPluginWrapperApi.fromWrappers(\n inputs.wrappers.map(wrapperInput => ({\n loader: wrapperInput.get(PluginWrapperBlueprint.dataRefs.wrapper),\n pluginId: wrapperInput.node.spec.plugin.id ?? 'app',\n })),\n );\n },\n }),\n );\n },\n});\n"],"names":[],"mappings":";;;AA2BO,MAAM,gBAAA,GAAmB,aAAa,iBAAA,CAAkB;AAAA,EAC7D,IAAA,EAAM,gBAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,UAAU,oBAAA,CAAqB,CAAC,sBAAA,CAAuB,QAAA,CAAS,OAAO,CAAC;AAAA,GAC1E;AAAA,EACA,OAAA,EAAS,CAAC,eAAA,EAAiB,EAAE,QAAO,KAAM;AACxC,IAAA,OAAO,eAAA;AAAA,MAAgB,kBACrB,YAAA,CAAa;AAAA,QACX,GAAA,EAAK,mBAAA;AAAA,QACL,MAAM,EAAC;AAAA,QACP,SAAS,MAAM;AACb,UAAA,OAAO,uBAAA,CAAwB,YAAA;AAAA,YAC7B,MAAA,CAAO,QAAA,CAAS,GAAA,CAAI,CAAA,YAAA,MAAiB;AAAA,cACnC,MAAA,EAAQ,YAAA,CAAa,GAAA,CAAI,sBAAA,CAAuB,SAAS,OAAO,CAAA;AAAA,cAChE,QAAA,EAAU,YAAA,CAAa,IAAA,CAAK,IAAA,CAAK,OAAO,EAAA,IAAM;AAAA,aAChD,CAAE;AAAA,WACJ;AAAA,QACF;AAAA,OACD;AAAA,KACH;AAAA,EACF;AACF,CAAC;;;;"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { jsx,
|
|
1
|
+
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { Progress as Progress$2, NotFoundErrorPage as NotFoundErrorPage$1, ErrorDisplay as ErrorDisplay$1, PageLayout as PageLayout$1 } from '@backstage/frontend-plugin-api';
|
|
3
3
|
import { SwappableComponentBlueprint } from '@backstage/plugin-app-react';
|
|
4
4
|
import { Progress as Progress$1, ErrorPage, ErrorPanel } from '@backstage/core-components';
|
|
5
5
|
import { PluginHeader } from '@backstage/ui';
|
|
6
6
|
import Button from '@material-ui/core/Button';
|
|
7
7
|
import { useMemo } from 'react';
|
|
8
|
+
import { useResolvedPath } from 'react-router-dom';
|
|
8
9
|
|
|
9
10
|
const Progress = SwappableComponentBlueprint.make({
|
|
10
11
|
name: "core-progress",
|
|
@@ -36,29 +37,40 @@ const PageLayout = SwappableComponentBlueprint.make({
|
|
|
36
37
|
params: (define) => define({
|
|
37
38
|
component: PageLayout$1,
|
|
38
39
|
loader: () => (props) => {
|
|
39
|
-
const {
|
|
40
|
-
|
|
40
|
+
const {
|
|
41
|
+
title,
|
|
42
|
+
icon,
|
|
43
|
+
noHeader,
|
|
44
|
+
titleLink,
|
|
45
|
+
headerActions,
|
|
46
|
+
tabs,
|
|
47
|
+
children
|
|
48
|
+
} = props;
|
|
49
|
+
const parentPath = useResolvedPath(".").pathname.replace(/\/$/, "");
|
|
50
|
+
const resolvedTabs = useMemo(
|
|
41
51
|
() => tabs?.map((tab) => ({
|
|
42
52
|
...tab,
|
|
53
|
+
href: tab.href.startsWith("/") ? tab.href : `${parentPath}/${tab.href}`.replace(/\/{2,}/g, "/"),
|
|
43
54
|
matchStrategy: "prefix"
|
|
44
55
|
})),
|
|
45
|
-
[tabs]
|
|
56
|
+
[tabs, parentPath]
|
|
46
57
|
);
|
|
47
|
-
if (
|
|
48
|
-
return /* @__PURE__ */
|
|
49
|
-
!noHeader && /* @__PURE__ */ jsx(
|
|
50
|
-
PluginHeader,
|
|
51
|
-
{
|
|
52
|
-
title,
|
|
53
|
-
icon,
|
|
54
|
-
tabs: tabsWithMatchStrategy,
|
|
55
|
-
customActions: headerActions
|
|
56
|
-
}
|
|
57
|
-
),
|
|
58
|
-
children
|
|
59
|
-
] });
|
|
58
|
+
if (noHeader) {
|
|
59
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
60
60
|
}
|
|
61
|
-
return /* @__PURE__ */
|
|
61
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
62
|
+
/* @__PURE__ */ jsx(
|
|
63
|
+
PluginHeader,
|
|
64
|
+
{
|
|
65
|
+
title,
|
|
66
|
+
icon,
|
|
67
|
+
titleLink,
|
|
68
|
+
tabs: resolvedTabs,
|
|
69
|
+
customActions: headerActions
|
|
70
|
+
}
|
|
71
|
+
),
|
|
72
|
+
children
|
|
73
|
+
] });
|
|
62
74
|
}
|
|
63
75
|
})
|
|
64
76
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.esm.js","sources":["../../src/extensions/components.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n NotFoundErrorPage as SwappableNotFoundErrorPage,\n Progress as SwappableProgress,\n ErrorDisplay as SwappableErrorDisplay,\n PageLayout as SwappablePageLayout,\n type PageLayoutProps,\n} from '@backstage/frontend-plugin-api';\nimport { SwappableComponentBlueprint } from '@backstage/plugin-app-react';\nimport {\n ErrorPage,\n ErrorPanel,\n Progress as ProgressComponent,\n} from '@backstage/core-components';\nimport { PluginHeader } from '@backstage/ui';\nimport Button from '@material-ui/core/Button';\nimport { useMemo } from 'react';\n\nexport const Progress = SwappableComponentBlueprint.make({\n name: 'core-progress',\n params: define =>\n define({\n component: SwappableProgress,\n loader: () => ProgressComponent,\n }),\n});\n\nexport const NotFoundErrorPage = SwappableComponentBlueprint.make({\n name: 'core-not-found-error-page',\n params: define =>\n define({\n component: SwappableNotFoundErrorPage,\n loader: () => () =>\n <ErrorPage status=\"404\" statusMessage=\"PAGE NOT FOUND\" />,\n }),\n});\n\nexport const ErrorDisplay = SwappableComponentBlueprint.make({\n name: 'core-error-display',\n params: define =>\n define({\n component: SwappableErrorDisplay,\n loader: () => props => {\n const { plugin, error, resetError } = props;\n const title = `Error in ${plugin?.id}`;\n return (\n <ErrorPanel title={title} error={error} defaultExpanded>\n <Button variant=\"outlined\" onClick={resetError}>\n Retry\n </Button>\n </ErrorPanel>\n );\n },\n }),\n});\n\nexport const PageLayout = SwappableComponentBlueprint.make({\n name: 'core-page-layout',\n params: define =>\n define({\n component: SwappablePageLayout,\n loader: () => (props: PageLayoutProps) => {\n const {
|
|
1
|
+
{"version":3,"file":"components.esm.js","sources":["../../src/extensions/components.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n NotFoundErrorPage as SwappableNotFoundErrorPage,\n Progress as SwappableProgress,\n ErrorDisplay as SwappableErrorDisplay,\n PageLayout as SwappablePageLayout,\n type PageLayoutProps,\n} from '@backstage/frontend-plugin-api';\nimport { SwappableComponentBlueprint } from '@backstage/plugin-app-react';\nimport {\n ErrorPage,\n ErrorPanel,\n Progress as ProgressComponent,\n} from '@backstage/core-components';\nimport { PluginHeader } from '@backstage/ui';\nimport Button from '@material-ui/core/Button';\nimport { useMemo } from 'react';\nimport { useResolvedPath } from 'react-router-dom';\n\nexport const Progress = SwappableComponentBlueprint.make({\n name: 'core-progress',\n params: define =>\n define({\n component: SwappableProgress,\n loader: () => ProgressComponent,\n }),\n});\n\nexport const NotFoundErrorPage = SwappableComponentBlueprint.make({\n name: 'core-not-found-error-page',\n params: define =>\n define({\n component: SwappableNotFoundErrorPage,\n loader: () => () =>\n <ErrorPage status=\"404\" statusMessage=\"PAGE NOT FOUND\" />,\n }),\n});\n\nexport const ErrorDisplay = SwappableComponentBlueprint.make({\n name: 'core-error-display',\n params: define =>\n define({\n component: SwappableErrorDisplay,\n loader: () => props => {\n const { plugin, error, resetError } = props;\n const title = `Error in ${plugin?.id}`;\n return (\n <ErrorPanel title={title} error={error} defaultExpanded>\n <Button variant=\"outlined\" onClick={resetError}>\n Retry\n </Button>\n </ErrorPanel>\n );\n },\n }),\n});\n\nexport const PageLayout = SwappableComponentBlueprint.make({\n name: 'core-page-layout',\n params: define =>\n define({\n component: SwappablePageLayout,\n loader: () => (props: PageLayoutProps) => {\n const {\n title,\n icon,\n noHeader,\n titleLink,\n headerActions,\n tabs,\n children,\n } = props;\n // TODO(Rugvip): Different solution to this path handling would be good\n const parentPath = useResolvedPath('.').pathname.replace(/\\/$/, '');\n const resolvedTabs = useMemo(\n () =>\n tabs?.map(tab => ({\n ...tab,\n href: tab.href.startsWith('/')\n ? tab.href\n : `${parentPath}/${tab.href}`.replace(/\\/{2,}/g, '/'),\n matchStrategy: 'prefix' as const,\n })),\n [tabs, parentPath],\n );\n\n if (noHeader) {\n return <>{children}</>;\n }\n\n return (\n <>\n <PluginHeader\n title={title}\n icon={icon}\n titleLink={titleLink}\n tabs={resolvedTabs}\n customActions={headerActions}\n />\n {children}\n </>\n );\n },\n }),\n});\n"],"names":["SwappableProgress","ProgressComponent","SwappableNotFoundErrorPage","SwappableErrorDisplay","SwappablePageLayout"],"mappings":";;;;;;;;;AAiCO,MAAM,QAAA,GAAW,4BAA4B,IAAA,CAAK;AAAA,EACvD,IAAA,EAAM,eAAA;AAAA,EACN,MAAA,EAAQ,YACN,MAAA,CAAO;AAAA,IACL,SAAA,EAAWA,UAAA;AAAA,IACX,QAAQ,MAAMC;AAAA,GACf;AACL,CAAC;AAEM,MAAM,iBAAA,GAAoB,4BAA4B,IAAA,CAAK;AAAA,EAChE,IAAA,EAAM,2BAAA;AAAA,EACN,MAAA,EAAQ,YACN,MAAA,CAAO;AAAA,IACL,SAAA,EAAWC,mBAAA;AAAA,IACX,MAAA,EAAQ,MAAM,sBACZ,GAAA,CAAC,aAAU,MAAA,EAAO,KAAA,EAAM,eAAc,gBAAA,EAAiB;AAAA,GAC1D;AACL,CAAC;AAEM,MAAM,YAAA,GAAe,4BAA4B,IAAA,CAAK;AAAA,EAC3D,IAAA,EAAM,oBAAA;AAAA,EACN,MAAA,EAAQ,YACN,MAAA,CAAO;AAAA,IACL,SAAA,EAAWC,cAAA;AAAA,IACX,MAAA,EAAQ,MAAM,CAAA,KAAA,KAAS;AACrB,MAAA,MAAM,EAAE,MAAA,EAAQ,KAAA,EAAO,UAAA,EAAW,GAAI,KAAA;AACtC,MAAA,MAAM,KAAA,GAAQ,CAAA,SAAA,EAAY,MAAA,EAAQ,EAAE,CAAA,CAAA;AACpC,MAAA,uBACE,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAc,KAAA,EAAc,eAAA,EAAe,IAAA,EACrD,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAQ,UAAA,EAAW,OAAA,EAAS,UAAA,EAAY,mBAEhD,CAAA,EACF,CAAA;AAAA,IAEJ;AAAA,GACD;AACL,CAAC;AAEM,MAAM,UAAA,GAAa,4BAA4B,IAAA,CAAK;AAAA,EACzD,IAAA,EAAM,kBAAA;AAAA,EACN,MAAA,EAAQ,YACN,MAAA,CAAO;AAAA,IACL,SAAA,EAAWC,YAAA;AAAA,IACX,MAAA,EAAQ,MAAM,CAAC,KAAA,KAA2B;AACxC,MAAA,MAAM;AAAA,QACJ,KAAA;AAAA,QACA,IAAA;AAAA,QACA,QAAA;AAAA,QACA,SAAA;AAAA,QACA,aAAA;AAAA,QACA,IAAA;AAAA,QACA;AAAA,OACF,GAAI,KAAA;AAEJ,MAAA,MAAM,aAAa,eAAA,CAAgB,GAAG,EAAE,QAAA,CAAS,OAAA,CAAQ,OAAO,EAAE,CAAA;AAClE,MAAA,MAAM,YAAA,GAAe,OAAA;AAAA,QACnB,MACE,IAAA,EAAM,GAAA,CAAI,CAAA,GAAA,MAAQ;AAAA,UAChB,GAAG,GAAA;AAAA,UACH,MAAM,GAAA,CAAI,IAAA,CAAK,UAAA,CAAW,GAAG,IACzB,GAAA,CAAI,IAAA,GACJ,CAAA,EAAG,UAAU,IAAI,GAAA,CAAI,IAAI,CAAA,CAAA,CAAG,OAAA,CAAQ,WAAW,GAAG,CAAA;AAAA,UACtD,aAAA,EAAe;AAAA,SACjB,CAAE,CAAA;AAAA,QACJ,CAAC,MAAM,UAAU;AAAA,OACnB;AAEA,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,uCAAU,QAAA,EAAS,CAAA;AAAA,MACrB;AAEA,MAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,YAAA;AAAA,UAAA;AAAA,YACC,KAAA;AAAA,YACA,IAAA;AAAA,YACA,SAAA;AAAA,YACA,IAAA,EAAM,YAAA;AAAA,YACN,aAAA,EAAe;AAAA;AAAA,SACjB;AAAA,QACC;AAAA,OAAA,EACH,CAAA;AAAA,IAEJ;AAAA,GACD;AACL,CAAC;;;;"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { OAuthRequestDialog
|
|
2
|
+
import { OAuthRequestDialog } from '@backstage/core-components';
|
|
3
3
|
import { AppRootElementBlueprint } from '@backstage/frontend-plugin-api';
|
|
4
|
+
import { ToastDisplay } from '../components/Toast/ToastDisplay.esm.js';
|
|
5
|
+
import '../components/Toast/ToastContainer.esm.js';
|
|
4
6
|
|
|
5
7
|
const oauthRequestDialogAppRootElement = AppRootElementBlueprint.make({
|
|
6
8
|
name: "oauth-request-dialog",
|
|
@@ -21,7 +23,7 @@ const alertDisplayAppRootElement = AppRootElementBlueprint.makeWithOverrides({
|
|
|
21
23
|
},
|
|
22
24
|
factory: (originalFactory, { config }) => {
|
|
23
25
|
return originalFactory({
|
|
24
|
-
element: /* @__PURE__ */ jsx(
|
|
26
|
+
element: /* @__PURE__ */ jsx(ToastDisplay, { transientTimeoutMs: config.transientTimeoutMs })
|
|
25
27
|
});
|
|
26
28
|
}
|
|
27
29
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elements.esm.js","sources":["../../src/extensions/elements.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {
|
|
1
|
+
{"version":3,"file":"elements.esm.js","sources":["../../src/extensions/elements.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { OAuthRequestDialog } from '@backstage/core-components';\nimport { AppRootElementBlueprint } from '@backstage/frontend-plugin-api';\nimport { ToastDisplay } from '../components/Toast';\n\nexport const oauthRequestDialogAppRootElement = AppRootElementBlueprint.make({\n name: 'oauth-request-dialog',\n params: {\n element: <OAuthRequestDialog />,\n },\n});\n\nexport const alertDisplayAppRootElement =\n AppRootElementBlueprint.makeWithOverrides({\n name: 'alert-display',\n config: {\n schema: {\n transientTimeoutMs: z => z.number().default(5000),\n anchorOrigin: z =>\n z\n .object({\n vertical: z.enum(['top', 'bottom']).default('top'),\n horizontal: z.enum(['left', 'center', 'right']).default('center'),\n })\n .default({}),\n },\n },\n factory: (originalFactory, { config }) => {\n return originalFactory({\n element: (\n <ToastDisplay transientTimeoutMs={config.transientTimeoutMs} />\n ),\n });\n },\n });\n"],"names":[],"mappings":";;;;;;AAoBO,MAAM,gCAAA,GAAmC,wBAAwB,IAAA,CAAK;AAAA,EAC3E,IAAA,EAAM,sBAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,OAAA,sBAAU,kBAAA,EAAA,EAAmB;AAAA;AAEjC,CAAC;AAEM,MAAM,0BAAA,GACX,wBAAwB,iBAAA,CAAkB;AAAA,EACxC,IAAA,EAAM,eAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,oBAAoB,CAAA,CAAA,KAAK,CAAA,CAAE,MAAA,EAAO,CAAE,QAAQ,GAAI,CAAA;AAAA,MAChD,YAAA,EAAc,CAAA,CAAA,KACZ,CAAA,CACG,MAAA,CAAO;AAAA,QACN,QAAA,EAAU,EAAE,IAAA,CAAK,CAAC,OAAO,QAAQ,CAAC,CAAA,CAAE,OAAA,CAAQ,KAAK,CAAA;AAAA,QACjD,UAAA,EAAY,CAAA,CAAE,IAAA,CAAK,CAAC,MAAA,EAAQ,UAAU,OAAO,CAAC,CAAA,CAAE,OAAA,CAAQ,QAAQ;AAAA,OACjE,CAAA,CACA,OAAA,CAAQ,EAAE;AAAA;AACjB,GACF;AAAA,EACA,OAAA,EAAS,CAAC,eAAA,EAAiB,EAAE,QAAO,KAAM;AACxC,IAAA,OAAO,eAAA,CAAgB;AAAA,MACrB,OAAA,kBACE,GAAA,CAAC,YAAA,EAAA,EAAa,kBAAA,EAAoB,OAAO,kBAAA,EAAoB;AAAA,KAEhE,CAAA;AAAA,EACH;AACF,CAAC;;;;"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useMemo, useState, useEffect } from 'react';
|
|
2
|
+
import { useApi, appThemeApiRef } from '@backstage/core-plugin-api';
|
|
3
|
+
import useObservable from 'react-use/esm/useObservable';
|
|
4
|
+
|
|
5
|
+
function useInvertedThemeMode() {
|
|
6
|
+
const appThemeApi = useApi(appThemeApiRef);
|
|
7
|
+
const themeId = useObservable(
|
|
8
|
+
appThemeApi.activeThemeId$(),
|
|
9
|
+
appThemeApi.getActiveThemeId()
|
|
10
|
+
);
|
|
11
|
+
const mediaQuery = useMemo(
|
|
12
|
+
() => typeof window.matchMedia === "function" ? window.matchMedia("(prefers-color-scheme: dark)") : void 0,
|
|
13
|
+
[]
|
|
14
|
+
);
|
|
15
|
+
const [prefersDark, setPrefersDark] = useState(mediaQuery?.matches ?? false);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!mediaQuery) return void 0;
|
|
18
|
+
const listener = (e) => setPrefersDark(e.matches);
|
|
19
|
+
mediaQuery.addEventListener("change", listener);
|
|
20
|
+
return () => mediaQuery.removeEventListener("change", listener);
|
|
21
|
+
}, [mediaQuery]);
|
|
22
|
+
const themes = appThemeApi.getInstalledThemes();
|
|
23
|
+
let currentVariant;
|
|
24
|
+
if (themeId !== void 0) {
|
|
25
|
+
currentVariant = themes.find((t) => t.id === themeId)?.variant;
|
|
26
|
+
}
|
|
27
|
+
if (!currentVariant) {
|
|
28
|
+
if (prefersDark) {
|
|
29
|
+
currentVariant = themes.find((t) => t.variant === "dark")?.variant;
|
|
30
|
+
}
|
|
31
|
+
currentVariant ??= themes.find((t) => t.variant === "light")?.variant;
|
|
32
|
+
currentVariant ??= themes[0]?.variant;
|
|
33
|
+
}
|
|
34
|
+
if (currentVariant === "dark") {
|
|
35
|
+
return "light";
|
|
36
|
+
}
|
|
37
|
+
return "dark";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { useInvertedThemeMode };
|
|
41
|
+
//# sourceMappingURL=useInvertedThemeMode.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInvertedThemeMode.esm.js","sources":["../../src/hooks/useInvertedThemeMode.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useState, useEffect, useMemo } from 'react';\nimport { useApi, appThemeApiRef } from '@backstage/core-plugin-api';\nimport useObservable from 'react-use/esm/useObservable';\n\ntype ThemeMode = 'light' | 'dark';\n\n/**\n * Returns the inverted theme mode based on the active app theme.\n * Uses the AppThemeApi to detect the current theme variant reactively.\n * When the theme is set to \"auto\" (no explicit selection), falls back to\n * the system preference via `prefers-color-scheme`.\n *\n * @returns The inverted theme mode ('light' when app is dark, 'dark' when app is light)\n * @internal\n */\nexport function useInvertedThemeMode(): ThemeMode {\n const appThemeApi = useApi(appThemeApiRef);\n\n const themeId = useObservable(\n appThemeApi.activeThemeId$(),\n appThemeApi.getActiveThemeId(),\n );\n\n // Track system color scheme preference for \"auto\" mode.\n // Guard against environments where matchMedia is unavailable (e.g. jsdom in tests).\n const mediaQuery = useMemo(\n () =>\n typeof window.matchMedia === 'function'\n ? window.matchMedia('(prefers-color-scheme: dark)')\n : undefined,\n [],\n );\n const [prefersDark, setPrefersDark] = useState(mediaQuery?.matches ?? false);\n\n useEffect(() => {\n if (!mediaQuery) return undefined;\n const listener = (e: MediaQueryListEvent) => setPrefersDark(e.matches);\n mediaQuery.addEventListener('change', listener);\n return () => mediaQuery.removeEventListener('change', listener);\n }, [mediaQuery]);\n\n // Resolve the active theme's variant, matching AppThemeProvider's logic:\n // 1. If a theme is explicitly selected, use its variant\n // 2. Otherwise (auto mode), use system preference to pick dark or light\n // 3. Fall back to the first installed theme\n const themes = appThemeApi.getInstalledThemes();\n let currentVariant: ThemeMode | undefined;\n\n if (themeId !== undefined) {\n currentVariant = themes.find(t => t.id === themeId)?.variant;\n }\n\n if (!currentVariant) {\n if (prefersDark) {\n currentVariant = themes.find(t => t.variant === 'dark')?.variant;\n }\n currentVariant ??= themes.find(t => t.variant === 'light')?.variant;\n currentVariant ??= themes[0]?.variant;\n }\n\n // Invert: if current is dark, toast should be light, and vice versa\n // Default to 'dark' if we can't determine (safe for most light-themed apps)\n if (currentVariant === 'dark') {\n return 'light';\n }\n return 'dark';\n}\n"],"names":[],"mappings":";;;;AA+BO,SAAS,oBAAA,GAAkC;AAChD,EAAA,MAAM,WAAA,GAAc,OAAO,cAAc,CAAA;AAEzC,EAAA,MAAM,OAAA,GAAU,aAAA;AAAA,IACd,YAAY,cAAA,EAAe;AAAA,IAC3B,YAAY,gBAAA;AAAiB,GAC/B;AAIA,EAAA,MAAM,UAAA,GAAa,OAAA;AAAA,IACjB,MACE,OAAO,MAAA,CAAO,UAAA,KAAe,aACzB,MAAA,CAAO,UAAA,CAAW,8BAA8B,CAAA,GAChD,MAAA;AAAA,IACN;AAAC,GACH;AACA,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,IAAI,QAAA,CAAS,UAAA,EAAY,WAAW,KAAK,CAAA;AAE3E,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAY,OAAO,MAAA;AACxB,IAAA,MAAM,QAAA,GAAW,CAAC,CAAA,KAA2B,cAAA,CAAe,EAAE,OAAO,CAAA;AACrE,IAAA,UAAA,CAAW,gBAAA,CAAiB,UAAU,QAAQ,CAAA;AAC9C,IAAA,OAAO,MAAM,UAAA,CAAW,mBAAA,CAAoB,QAAA,EAAU,QAAQ,CAAA;AAAA,EAChE,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAMf,EAAA,MAAM,MAAA,GAAS,YAAY,kBAAA,EAAmB;AAC9C,EAAA,IAAI,cAAA;AAEJ,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,cAAA,GAAiB,OAAO,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,EAAA,KAAO,OAAO,CAAA,EAAG,OAAA;AAAA,EACvD;AAEA,EAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,cAAA,GAAiB,OAAO,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,OAAA,KAAY,MAAM,CAAA,EAAG,OAAA;AAAA,IAC3D;AACA,IAAA,cAAA,KAAmB,OAAO,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,OAAA,KAAY,OAAO,CAAA,EAAG,OAAA;AAC5D,IAAA,cAAA,KAAmB,MAAA,CAAO,CAAC,CAAA,EAAG,OAAA;AAAA,EAChC;AAIA,EAAA,IAAI,mBAAmB,MAAA,EAAQ;AAC7B,IAAA,OAAO,OAAA;AAAA,EACT;AACA,EAAA,OAAO,MAAA;AACT;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -82,7 +82,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
|
|
|
82
82
|
}>;
|
|
83
83
|
children: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}>, {
|
|
84
84
|
singleton: true;
|
|
85
|
-
optional:
|
|
85
|
+
optional: true;
|
|
86
86
|
internal: false;
|
|
87
87
|
}>;
|
|
88
88
|
elements: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}>, {
|
|
@@ -372,11 +372,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
|
|
|
372
372
|
configInput: {};
|
|
373
373
|
output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
|
|
374
374
|
inputs: {
|
|
375
|
-
wrappers: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<() => Promise<{
|
|
376
|
-
component: react.ComponentType<{
|
|
377
|
-
children: react.ReactNode;
|
|
378
|
-
}>;
|
|
379
|
-
}>, "core.plugin-wrapper.loader", {}>, {
|
|
375
|
+
wrappers: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<() => Promise<_backstage_frontend_plugin_api.PluginWrapperDefinition>, "core.plugin-wrapper.loader", {}>, {
|
|
380
376
|
singleton: false;
|
|
381
377
|
optional: false;
|
|
382
378
|
internal: false;
|
|
@@ -431,6 +427,24 @@ declare const appPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugi
|
|
|
431
427
|
name: "swappable-components";
|
|
432
428
|
params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
|
|
433
429
|
}>;
|
|
430
|
+
"api:app/toast": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
431
|
+
kind: "api";
|
|
432
|
+
name: "toast";
|
|
433
|
+
config: {};
|
|
434
|
+
configInput: {};
|
|
435
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
|
|
436
|
+
inputs: {};
|
|
437
|
+
params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
|
|
438
|
+
}>;
|
|
439
|
+
"api:app/toast-forwarder": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
440
|
+
kind: "api";
|
|
441
|
+
name: "toast-forwarder";
|
|
442
|
+
config: {};
|
|
443
|
+
configInput: {};
|
|
444
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
|
|
445
|
+
inputs: {};
|
|
446
|
+
params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
|
|
447
|
+
}>;
|
|
434
448
|
"api:app/translations": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
435
449
|
config: {};
|
|
436
450
|
configInput: {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
function styleInject(css, ref) {
|
|
2
|
+
if ( ref === void 0 ) ref = {};
|
|
3
|
+
var insertAt = ref.insertAt;
|
|
4
|
+
|
|
5
|
+
if (typeof document === 'undefined') { return; }
|
|
6
|
+
|
|
7
|
+
var head = document.head || document.getElementsByTagName('head')[0];
|
|
8
|
+
var style = document.createElement('style');
|
|
9
|
+
style.type = 'text/css';
|
|
10
|
+
|
|
11
|
+
if (insertAt === 'top') {
|
|
12
|
+
if (head.firstChild) {
|
|
13
|
+
head.insertBefore(style, head.firstChild);
|
|
14
|
+
} else {
|
|
15
|
+
head.appendChild(style);
|
|
16
|
+
}
|
|
17
|
+
} else {
|
|
18
|
+
head.appendChild(style);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (style.styleSheet) {
|
|
22
|
+
style.styleSheet.cssText = css;
|
|
23
|
+
} else {
|
|
24
|
+
style.appendChild(document.createTextNode(css));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { styleInject as default };
|
|
29
|
+
//# sourceMappingURL=style-inject.es.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style-inject.es.esm.js","sources":["../../../../../../node_modules/style-inject/dist/style-inject.es.js"],"sourcesContent":["function styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nexport default styleInject;\n"],"names":[],"mappings":"AAAA,SAAS,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE;AAC/B,EAAE,KAAK,GAAG,KAAK,MAAM,GAAG,GAAG,GAAG,EAAE;AAChC,EAAE,IAAI,QAAQ,GAAG,GAAG,CAAC,QAAQ;;AAE7B,EAAE,IAAY,OAAO,QAAQ,KAAK,WAAW,EAAE,EAAE,OAAO,CAAC;;AAEzD,EAAE,IAAI,IAAI,GAAG,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACtE,EAAE,IAAI,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC;AAC7C,EAAE,KAAK,CAAC,IAAI,GAAG,UAAU;;AAEzB,EAAE,IAAI,QAAQ,KAAK,KAAK,EAAE;AAC1B,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;AACzB,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC;AAC/C,IAAI,CAAC,MAAM;AACX,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AAC7B,IAAI;AACJ,EAAE,CAAC,MAAM;AACT,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;AAC3B,EAAE;;AAEF,EAAE,IAAI,KAAK,CAAC,UAAU,EAAE;AACxB,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,GAAG,GAAG;AAClC,EAAE,CAAC,MAAM;AACT,IAAI,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;AACnD,EAAE;AACF;;;;","x_google_ignoreList":[0]}
|
package/dist/packages/core-app-api/src/apis/implementations/AlertApi/AlertApiForwarder.esm.js
CHANGED
|
@@ -5,7 +5,14 @@ class AlertApiForwarder {
|
|
|
5
5
|
subject = new PublishSubject();
|
|
6
6
|
recentAlerts = [];
|
|
7
7
|
maxBufferSize = 10;
|
|
8
|
+
hasWarnedDeprecation = false;
|
|
8
9
|
post(alert) {
|
|
10
|
+
if (!this.hasWarnedDeprecation) {
|
|
11
|
+
this.hasWarnedDeprecation = true;
|
|
12
|
+
console.warn(
|
|
13
|
+
'AlertApi is deprecated and will be removed in a future release. Please migrate to ToastApi from @backstage/frontend-plugin-api. ToastApi provides richer features including title/description, links, icons, and per-toast timeouts. Example: toastApi.post({ title: "Saved!", status: "success", timeout: 5000 })'
|
|
14
|
+
);
|
|
15
|
+
}
|
|
9
16
|
this.recentAlerts.push(alert);
|
|
10
17
|
if (this.recentAlerts.length > this.maxBufferSize) {
|
|
11
18
|
this.recentAlerts.shift();
|
package/dist/packages/core-app-api/src/apis/implementations/AlertApi/AlertApiForwarder.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AlertApiForwarder.esm.js","sources":["../../../../../../../../../packages/core-app-api/src/apis/implementations/AlertApi/AlertApiForwarder.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AlertApi, AlertMessage } from '@backstage/core-plugin-api';\nimport { Observable } from '@backstage/types';\nimport { PublishSubject } from '../../../lib/subjects';\nimport ObservableImpl from 'zen-observable';\n\n/**\n * Base implementation for the AlertApi that simply forwards alerts to consumers.\n *\n * Recent alerts are buffered and replayed to new subscribers to prevent\n * missing alerts that were posted before subscription.\n *\n * @public\n */\nexport class AlertApiForwarder implements AlertApi {\n private readonly subject = new PublishSubject<AlertMessage>();\n private readonly recentAlerts: AlertMessage[] = [];\n private readonly maxBufferSize = 10;\n\n post(alert: AlertMessage) {\n this.recentAlerts.push(alert);\n if (this.recentAlerts.length > this.maxBufferSize) {\n this.recentAlerts.shift();\n }\n this.subject.next(alert);\n }\n\n alert$(): Observable<AlertMessage> {\n return new ObservableImpl<AlertMessage>(subscriber => {\n for (const alert of this.recentAlerts) {\n subscriber.next(alert);\n }\n return this.subject.subscribe(subscriber);\n });\n }\n}\n"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"AlertApiForwarder.esm.js","sources":["../../../../../../../../../packages/core-app-api/src/apis/implementations/AlertApi/AlertApiForwarder.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AlertApi, AlertMessage } from '@backstage/core-plugin-api';\nimport { Observable } from '@backstage/types';\nimport { PublishSubject } from '../../../lib/subjects';\nimport ObservableImpl from 'zen-observable';\n\n/**\n * Base implementation for the AlertApi that simply forwards alerts to consumers.\n *\n * Recent alerts are buffered and replayed to new subscribers to prevent\n * missing alerts that were posted before subscription.\n *\n * @public\n * @deprecated Use ToastApi instead. AlertApi will be removed in a future release.\n */\nexport class AlertApiForwarder implements AlertApi {\n private readonly subject = new PublishSubject<AlertMessage>();\n private readonly recentAlerts: AlertMessage[] = [];\n private readonly maxBufferSize = 10;\n private hasWarnedDeprecation = false;\n\n post(alert: AlertMessage) {\n if (!this.hasWarnedDeprecation) {\n this.hasWarnedDeprecation = true;\n // eslint-disable-next-line no-console\n console.warn(\n 'AlertApi is deprecated and will be removed in a future release. ' +\n 'Please migrate to ToastApi from @backstage/frontend-plugin-api. ' +\n 'ToastApi provides richer features including title/description, links, icons, and per-toast timeouts. ' +\n 'Example: toastApi.post({ title: \"Saved!\", status: \"success\", timeout: 5000 })',\n );\n }\n this.recentAlerts.push(alert);\n if (this.recentAlerts.length > this.maxBufferSize) {\n this.recentAlerts.shift();\n }\n this.subject.next(alert);\n }\n\n alert$(): Observable<AlertMessage> {\n return new ObservableImpl<AlertMessage>(subscriber => {\n for (const alert of this.recentAlerts) {\n subscriber.next(alert);\n }\n return this.subject.subscribe(subscriber);\n });\n }\n}\n"],"names":[],"mappings":";;;AA8BO,MAAM,iBAAA,CAAsC;AAAA,EAChC,OAAA,GAAU,IAAI,cAAA,EAA6B;AAAA,EAC3C,eAA+B,EAAC;AAAA,EAChC,aAAA,GAAgB,EAAA;AAAA,EACzB,oBAAA,GAAuB,KAAA;AAAA,EAE/B,KAAK,KAAA,EAAqB;AACxB,IAAA,IAAI,CAAC,KAAK,oBAAA,EAAsB;AAC9B,MAAA,IAAA,CAAK,oBAAA,GAAuB,IAAA;AAE5B,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN;AAAA,OAIF;AAAA,IACF;AACA,IAAA,IAAA,CAAK,YAAA,CAAa,KAAK,KAAK,CAAA;AAC5B,IAAA,IAAI,IAAA,CAAK,YAAA,CAAa,MAAA,GAAS,IAAA,CAAK,aAAA,EAAe;AACjD,MAAA,IAAA,CAAK,aAAa,KAAA,EAAM;AAAA,IAC1B;AACA,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,EACzB;AAAA,EAEA,MAAA,GAAmC;AACjC,IAAA,OAAO,IAAI,eAA6B,CAAA,UAAA,KAAc;AACpD,MAAA,KAAA,MAAW,KAAA,IAAS,KAAK,YAAA,EAAc;AACrC,QAAA,UAAA,CAAW,KAAK,KAAK,CAAA;AAAA,MACvB;AACA,MAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,SAAA,CAAU,UAAU,CAAA;AAAA,IAC1C,CAAC,CAAA;AAAA,EACH;AACF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.esm.js","sources":["../../../../../../../../../../packages/core-app-api/src/apis/implementations/auth/saml/types.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n BackstageIdentityResponse,\n ProfileInfo,\n} from '@backstage/core-plugin-api';\nimport { z } from 'zod';\n\n/** @internal */\nexport type SamlSession = {\n profile: ProfileInfo;\n backstageIdentity: BackstageIdentityResponse;\n};\n\n/** @internal */\nexport const samlSessionSchema: z.ZodSchema<SamlSession> = z.object({\n profile: z.object({\n email: z.string().optional(),\n displayName: z.string().optional(),\n picture: z.string().optional(),\n }),\n backstageIdentity: z.object({\n token: z.string(),\n identity: z.object({\n type: z.literal('user'),\n userEntityRef: z.string(),\n ownershipEntityRefs: z.array(z.string()),\n }),\n }),\n});\n"],"names":[],"mappings":";;AA6B2D,EAAE,MAAA,CAAO;AAAA,EAClE,OAAA,EAAS,EAAE,MAAA,CAAO;AAAA,IAChB,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IAC3B,WAAA,EAAa,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IACjC,OAAA,EAAS,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAAS,GAC9B,CAAA;AAAA,EACD,iBAAA,EAAmB,EAAE,MAAA,CAAO;AAAA,IAC1B,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA,IAChB,QAAA,EAAU,EAAE,MAAA,CAAO;AAAA,MACjB,IAAA,EAAM,CAAA,CAAE,OAAA,CAAQ,MAAM,CAAA;AAAA,MACtB,aAAA,EAAe,EAAE,MAAA,EAAO;AAAA,MACxB,mBAAA,EAAqB,CAAA,CAAE,KAAA,CAAM,CAAA,CAAE,QAAQ;AAAA,KACxC;AAAA,GACF;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.esm.js","sources":["../../../../../../../../../../packages/core-app-api/src/apis/implementations/auth/saml/types.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n BackstageIdentityResponse,\n ProfileInfo,\n} from '@backstage/core-plugin-api';\nimport { z } from 'zod/v3';\n\n/** @internal */\nexport type SamlSession = {\n profile: ProfileInfo;\n backstageIdentity: BackstageIdentityResponse;\n};\n\n/** @internal */\nexport const samlSessionSchema: z.ZodSchema<SamlSession> = z.object({\n profile: z.object({\n email: z.string().optional(),\n displayName: z.string().optional(),\n picture: z.string().optional(),\n }),\n backstageIdentity: z.object({\n token: z.string(),\n identity: z.object({\n type: z.literal('user'),\n userEntityRef: z.string(),\n ownershipEntityRefs: z.array(z.string()),\n }),\n }),\n});\n"],"names":[],"mappings":";;AA6B2D,EAAE,MAAA,CAAO;AAAA,EAClE,OAAA,EAAS,EAAE,MAAA,CAAO;AAAA,IAChB,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IAC3B,WAAA,EAAa,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IACjC,OAAA,EAAS,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAAS,GAC9B,CAAA;AAAA,EACD,iBAAA,EAAmB,EAAE,MAAA,CAAO;AAAA,IAC1B,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA,IAChB,QAAA,EAAU,EAAE,MAAA,CAAO;AAAA,MACjB,IAAA,EAAM,CAAA,CAAE,OAAA,CAAQ,MAAM,CAAA;AAAA,MACtB,aAAA,EAAe,EAAE,MAAA,EAAO;AAAA,MACxB,mBAAA,EAAqB,CAAA,CAAE,KAAA,CAAM,CAAA,CAAE,QAAQ;AAAA,KACxC;AAAA,GACF;AACH,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { useContext, useState } from 'react';
|
|
3
|
-
import { attachComponentData, useApp, useApi, configApiRef } from '@backstage/core-plugin-api';
|
|
3
|
+
import { attachComponentData, useApp, useApi, configApiRef, useAnalytics } from '@backstage/core-plugin-api';
|
|
4
|
+
import { BUIProvider } from '@backstage/ui';
|
|
4
5
|
import { InternalAppContext } from './InternalAppContext.esm.js';
|
|
5
6
|
import { isReactRouterBeta } from './isReactRouterBeta.esm.js';
|
|
6
7
|
import { RouteTracker } from '../routing/RouteTracker.esm.js';
|
|
@@ -66,18 +67,18 @@ function AppRouter(props) {
|
|
|
66
67
|
{ signOutTargetUrl: basePath || "/" }
|
|
67
68
|
);
|
|
68
69
|
if (isReactRouterBeta()) {
|
|
69
|
-
return /* @__PURE__ */
|
|
70
|
+
return /* @__PURE__ */ jsx(RouterComponent, { children: /* @__PURE__ */ jsxs(BUIProvider, { useAnalytics, children: [
|
|
70
71
|
/* @__PURE__ */ jsx(RouteTracker, { routeObjects }),
|
|
71
72
|
/* @__PURE__ */ jsx(Routes, { children: /* @__PURE__ */ jsx(Route, { path: mountPath, element: /* @__PURE__ */ jsx(Fragment, { children: props.children }) }) })
|
|
72
|
-
] });
|
|
73
|
+
] }) });
|
|
73
74
|
}
|
|
74
|
-
return /* @__PURE__ */
|
|
75
|
+
return /* @__PURE__ */ jsx(RouterComponent, { basename: basePath, children: /* @__PURE__ */ jsxs(BUIProvider, { useAnalytics, children: [
|
|
75
76
|
/* @__PURE__ */ jsx(RouteTracker, { routeObjects }),
|
|
76
77
|
props.children
|
|
77
|
-
] });
|
|
78
|
+
] }) });
|
|
78
79
|
}
|
|
79
80
|
if (isReactRouterBeta()) {
|
|
80
|
-
return /* @__PURE__ */
|
|
81
|
+
return /* @__PURE__ */ jsx(RouterComponent, { children: /* @__PURE__ */ jsxs(BUIProvider, { useAnalytics, children: [
|
|
81
82
|
/* @__PURE__ */ jsx(RouteTracker, { routeObjects }),
|
|
82
83
|
/* @__PURE__ */ jsx(
|
|
83
84
|
SignInPageWrapper,
|
|
@@ -87,9 +88,9 @@ function AppRouter(props) {
|
|
|
87
88
|
children: /* @__PURE__ */ jsx(Routes, { children: /* @__PURE__ */ jsx(Route, { path: mountPath, element: /* @__PURE__ */ jsx(Fragment, { children: props.children }) }) })
|
|
88
89
|
}
|
|
89
90
|
)
|
|
90
|
-
] });
|
|
91
|
+
] }) });
|
|
91
92
|
}
|
|
92
|
-
return /* @__PURE__ */
|
|
93
|
+
return /* @__PURE__ */ jsx(RouterComponent, { basename: basePath, children: /* @__PURE__ */ jsxs(BUIProvider, { useAnalytics, children: [
|
|
93
94
|
/* @__PURE__ */ jsx(RouteTracker, { routeObjects }),
|
|
94
95
|
/* @__PURE__ */ jsx(
|
|
95
96
|
SignInPageWrapper,
|
|
@@ -99,7 +100,7 @@ function AppRouter(props) {
|
|
|
99
100
|
children: props.children
|
|
100
101
|
}
|
|
101
102
|
)
|
|
102
|
-
] });
|
|
103
|
+
] }) });
|
|
103
104
|
}
|
|
104
105
|
attachComponentData(AppRouter, "core.type", "AppRouter");
|
|
105
106
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppRouter.esm.js","sources":["../../../../../../../packages/core-app-api/src/app/AppRouter.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useContext, ReactNode, ComponentType, useState } from 'react';\nimport {\n attachComponentData,\n ConfigApi,\n configApiRef,\n IdentityApi,\n SignInPageProps,\n useApi,\n useApp,\n} from '@backstage/core-plugin-api';\nimport { InternalAppContext } from './InternalAppContext';\nimport { isReactRouterBeta } from './isReactRouterBeta';\nimport { RouteTracker } from '../routing/RouteTracker';\nimport { Route, Routes } from 'react-router-dom';\nimport { AppIdentityProxy } from '../apis/implementations/IdentityApi/AppIdentityProxy';\n\n/**\n * Get the app base path from the configured app baseUrl.\n *\n * The returned path does not have a trailing slash.\n */\nexport function getBasePath(configApi: ConfigApi) {\n if (!isReactRouterBeta()) {\n // When using rr v6 stable the base path is handled through the\n // basename prop on the router component instead.\n return '';\n }\n\n return readBasePath(configApi);\n}\n\n/**\n * Read the configured base path.\n *\n * The returned path does not have a trailing slash.\n */\nfunction readBasePath(configApi: ConfigApi) {\n let { pathname } = new URL(\n configApi.getOptionalString('app.baseUrl') ?? '/',\n 'http://sample.dev', // baseUrl can be specified as just a path\n );\n pathname = pathname.replace(/\\/*$/, '');\n return pathname;\n}\n\n// This wraps the sign-in page and waits for sign-in to be completed before rendering the app\nfunction SignInPageWrapper({\n component: Component,\n appIdentityProxy,\n children,\n}: {\n component: ComponentType<SignInPageProps>;\n appIdentityProxy: AppIdentityProxy;\n children: ReactNode;\n}) {\n const [identityApi, setIdentityApi] = useState<IdentityApi>();\n const configApi = useApi(configApiRef);\n const basePath = readBasePath(configApi);\n\n if (!identityApi) {\n return <Component onSignInSuccess={setIdentityApi} />;\n }\n\n appIdentityProxy.setTarget(identityApi, {\n signOutTargetUrl: basePath || '/',\n });\n return <>{children}</>;\n}\n\n/**\n * Props for the {@link AppRouter} component.\n * @public\n */\nexport interface AppRouterProps {\n children?: ReactNode;\n}\n\n/**\n * App router and sign-in page wrapper.\n *\n * @public\n * @remarks\n *\n * The AppRouter provides the routing context and renders the sign-in page.\n * Until the user has successfully signed in, this component will render\n * the sign-in page. Once the user has signed-in, it will instead render\n * the app, while providing routing and route tracking for the app.\n */\nexport function AppRouter(props: AppRouterProps) {\n const { Router: RouterComponent, SignInPage: SignInPageComponent } =\n useApp().getComponents();\n\n const configApi = useApi(configApiRef);\n const basePath = readBasePath(configApi);\n const mountPath = `${basePath}/*`;\n const internalAppContext = useContext(InternalAppContext);\n if (!internalAppContext) {\n throw new Error('AppRouter must be rendered within the AppProvider');\n }\n const { routeObjects, appIdentityProxy } = internalAppContext;\n\n // If the app hasn't configured a sign-in page, we just continue as guest.\n if (!SignInPageComponent) {\n appIdentityProxy.setTarget(\n {\n getUserId: () => 'guest',\n getIdToken: async () => undefined,\n getProfile: () => ({\n email: 'guest@example.com',\n displayName: 'Guest',\n }),\n getProfileInfo: async () => ({\n email: 'guest@example.com',\n displayName: 'Guest',\n }),\n getBackstageIdentity: async () => ({\n type: 'user',\n userEntityRef: 'user:default/guest',\n ownershipEntityRefs: ['user:default/guest'],\n }),\n getCredentials: async () => ({}),\n signOut: async () => {},\n },\n { signOutTargetUrl: basePath || '/' },\n );\n\n if (isReactRouterBeta()) {\n return (\n <RouterComponent>\n <RouteTracker routeObjects={routeObjects} />\n
|
|
1
|
+
{"version":3,"file":"AppRouter.esm.js","sources":["../../../../../../../packages/core-app-api/src/app/AppRouter.tsx"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useContext, ReactNode, ComponentType, useState } from 'react';\nimport {\n attachComponentData,\n ConfigApi,\n configApiRef,\n IdentityApi,\n SignInPageProps,\n useApi,\n useApp,\n useAnalytics,\n} from '@backstage/core-plugin-api';\nimport { BUIProvider } from '@backstage/ui';\nimport { InternalAppContext } from './InternalAppContext';\nimport { isReactRouterBeta } from './isReactRouterBeta';\nimport { RouteTracker } from '../routing/RouteTracker';\nimport { Route, Routes } from 'react-router-dom';\nimport { AppIdentityProxy } from '../apis/implementations/IdentityApi/AppIdentityProxy';\n\n/**\n * Get the app base path from the configured app baseUrl.\n *\n * The returned path does not have a trailing slash.\n */\nexport function getBasePath(configApi: ConfigApi) {\n if (!isReactRouterBeta()) {\n // When using rr v6 stable the base path is handled through the\n // basename prop on the router component instead.\n return '';\n }\n\n return readBasePath(configApi);\n}\n\n/**\n * Read the configured base path.\n *\n * The returned path does not have a trailing slash.\n */\nfunction readBasePath(configApi: ConfigApi) {\n let { pathname } = new URL(\n configApi.getOptionalString('app.baseUrl') ?? '/',\n 'http://sample.dev', // baseUrl can be specified as just a path\n );\n pathname = pathname.replace(/\\/*$/, '');\n return pathname;\n}\n\n// This wraps the sign-in page and waits for sign-in to be completed before rendering the app\nfunction SignInPageWrapper({\n component: Component,\n appIdentityProxy,\n children,\n}: {\n component: ComponentType<SignInPageProps>;\n appIdentityProxy: AppIdentityProxy;\n children: ReactNode;\n}) {\n const [identityApi, setIdentityApi] = useState<IdentityApi>();\n const configApi = useApi(configApiRef);\n const basePath = readBasePath(configApi);\n\n if (!identityApi) {\n return <Component onSignInSuccess={setIdentityApi} />;\n }\n\n appIdentityProxy.setTarget(identityApi, {\n signOutTargetUrl: basePath || '/',\n });\n return <>{children}</>;\n}\n\n/**\n * Props for the {@link AppRouter} component.\n * @public\n */\nexport interface AppRouterProps {\n children?: ReactNode;\n}\n\n/**\n * App router and sign-in page wrapper.\n *\n * @public\n * @remarks\n *\n * The AppRouter provides the routing context and renders the sign-in page.\n * Until the user has successfully signed in, this component will render\n * the sign-in page. Once the user has signed-in, it will instead render\n * the app, while providing routing and route tracking for the app.\n */\nexport function AppRouter(props: AppRouterProps) {\n const { Router: RouterComponent, SignInPage: SignInPageComponent } =\n useApp().getComponents();\n\n const configApi = useApi(configApiRef);\n const basePath = readBasePath(configApi);\n const mountPath = `${basePath}/*`;\n const internalAppContext = useContext(InternalAppContext);\n if (!internalAppContext) {\n throw new Error('AppRouter must be rendered within the AppProvider');\n }\n const { routeObjects, appIdentityProxy } = internalAppContext;\n\n // If the app hasn't configured a sign-in page, we just continue as guest.\n if (!SignInPageComponent) {\n appIdentityProxy.setTarget(\n {\n getUserId: () => 'guest',\n getIdToken: async () => undefined,\n getProfile: () => ({\n email: 'guest@example.com',\n displayName: 'Guest',\n }),\n getProfileInfo: async () => ({\n email: 'guest@example.com',\n displayName: 'Guest',\n }),\n getBackstageIdentity: async () => ({\n type: 'user',\n userEntityRef: 'user:default/guest',\n ownershipEntityRefs: ['user:default/guest'],\n }),\n getCredentials: async () => ({}),\n signOut: async () => {},\n },\n { signOutTargetUrl: basePath || '/' },\n );\n\n if (isReactRouterBeta()) {\n return (\n <RouterComponent>\n <BUIProvider useAnalytics={useAnalytics}>\n <RouteTracker routeObjects={routeObjects} />\n <Routes>\n <Route path={mountPath} element={<>{props.children}</>} />\n </Routes>\n </BUIProvider>\n </RouterComponent>\n );\n }\n\n return (\n <RouterComponent basename={basePath}>\n <BUIProvider useAnalytics={useAnalytics}>\n <RouteTracker routeObjects={routeObjects} />\n {props.children}\n </BUIProvider>\n </RouterComponent>\n );\n }\n\n if (isReactRouterBeta()) {\n return (\n <RouterComponent>\n <BUIProvider useAnalytics={useAnalytics}>\n <RouteTracker routeObjects={routeObjects} />\n <SignInPageWrapper\n component={SignInPageComponent}\n appIdentityProxy={appIdentityProxy}\n >\n <Routes>\n <Route path={mountPath} element={<>{props.children}</>} />\n </Routes>\n </SignInPageWrapper>\n </BUIProvider>\n </RouterComponent>\n );\n }\n\n return (\n <RouterComponent basename={basePath}>\n <BUIProvider useAnalytics={useAnalytics}>\n <RouteTracker routeObjects={routeObjects} />\n <SignInPageWrapper\n component={SignInPageComponent}\n appIdentityProxy={appIdentityProxy}\n >\n {props.children}\n </SignInPageWrapper>\n </BUIProvider>\n </RouterComponent>\n );\n}\n\nattachComponentData(AppRouter, 'core.type', 'AppRouter');\n"],"names":[],"mappings":"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"}
|
package/dist/packages/frontend-app-api/src/apis/implementations/IconsApi/DefaultIconsApi.esm.js
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
|
-
import { isValidElement, createElement } from 'react';
|
|
1
|
+
import { isValidElement, createElement, cloneElement } from 'react';
|
|
2
2
|
|
|
3
|
+
const legacyFontSizeMap = {
|
|
4
|
+
inherit: "inherit",
|
|
5
|
+
small: "1.25rem",
|
|
6
|
+
medium: "1.5rem",
|
|
7
|
+
large: "2.1875rem"
|
|
8
|
+
};
|
|
9
|
+
function mergeClassNames(...classNames) {
|
|
10
|
+
const merged = classNames.filter(Boolean).join(" ");
|
|
11
|
+
if (merged) {
|
|
12
|
+
return merged;
|
|
13
|
+
}
|
|
14
|
+
return void 0;
|
|
15
|
+
}
|
|
3
16
|
class DefaultIconsApi {
|
|
4
17
|
#icons;
|
|
5
18
|
#components = /* @__PURE__ */ new Map();
|
|
@@ -11,7 +24,10 @@ class DefaultIconsApi {
|
|
|
11
24
|
return [key, value];
|
|
12
25
|
}
|
|
13
26
|
deprecatedKeys.push(key);
|
|
14
|
-
return [
|
|
27
|
+
return [
|
|
28
|
+
key,
|
|
29
|
+
createElement(value, { fontSize: "inherit" })
|
|
30
|
+
];
|
|
15
31
|
})
|
|
16
32
|
);
|
|
17
33
|
if (deprecatedKeys.length > 0) {
|
|
@@ -33,7 +49,27 @@ class DefaultIconsApi {
|
|
|
33
49
|
if (el === void 0) {
|
|
34
50
|
return void 0;
|
|
35
51
|
}
|
|
36
|
-
component = () =>
|
|
52
|
+
component = (props) => {
|
|
53
|
+
if (el === null) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
const {
|
|
57
|
+
fontSize = "medium",
|
|
58
|
+
className,
|
|
59
|
+
style,
|
|
60
|
+
...rest
|
|
61
|
+
} = props;
|
|
62
|
+
const elementProps = el.props;
|
|
63
|
+
return cloneElement(el, {
|
|
64
|
+
...rest,
|
|
65
|
+
className: mergeClassNames(elementProps.className, className),
|
|
66
|
+
style: {
|
|
67
|
+
...elementProps.style,
|
|
68
|
+
fontSize: legacyFontSizeMap[fontSize],
|
|
69
|
+
...style
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
};
|
|
37
73
|
this.#components.set(key, component);
|
|
38
74
|
return component;
|
|
39
75
|
}
|