@backstage/plugin-app 0.1.0-next.0 → 0.1.0-next.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 CHANGED
@@ -1,5 +1,59 @@
1
1
  # @backstage/plugin-app
2
2
 
3
+ ## 0.1.0-next.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 57bf6ae: Fix issue with `AlertDisplay` and other components defined with `AppRootElementBlueprint` not being rendered when at the `SignInWrapper`
8
+ - 836127c: Updated dependency `@testing-library/react` to `^16.0.0`.
9
+ - Updated dependencies
10
+ - @backstage/core-components@0.14.11-next.1
11
+ - @backstage/core-plugin-api@1.9.4-next.0
12
+ - @backstage/frontend-plugin-api@0.8.0-next.2
13
+ - @backstage/theme@0.5.7-next.0
14
+ - @backstage/plugin-permission-react@0.4.26-next.0
15
+
16
+ ## 0.1.0-next.1
17
+
18
+ ### Patch Changes
19
+
20
+ - 52f9c5a: Deprecated the `namespace` option for `createExtensionBlueprint` and `createExtension`, these are no longer required and will default to the `pluginId` instead.
21
+
22
+ You can migrate some of your extensions that use `createExtensionOverrides` to using `createFrontendModule` instead and providing a `pluginId` there.
23
+
24
+ ```ts
25
+ // Before
26
+ createExtensionOverrides({
27
+ extensions: [
28
+ createExtension({
29
+ name: 'my-extension',
30
+ namespace: 'my-namespace',
31
+ kind: 'test',
32
+ ...
33
+ })
34
+ ],
35
+ });
36
+
37
+ // After
38
+ createFrontendModule({
39
+ pluginId: 'my-namespace',
40
+ extensions: [
41
+ createExtension({
42
+ name: 'my-extension',
43
+ kind: 'test',
44
+ ...
45
+ })
46
+ ],
47
+ });
48
+ ```
49
+
50
+ - Updated dependencies
51
+ - @backstage/frontend-plugin-api@0.8.0-next.1
52
+ - @backstage/core-components@0.14.11-next.0
53
+ - @backstage/core-plugin-api@1.9.3
54
+ - @backstage/theme@0.5.6
55
+ - @backstage/plugin-permission-react@0.4.25
56
+
3
57
  ## 0.1.0-next.0
4
58
 
5
59
  ### Minor Changes
@@ -18,7 +18,6 @@ import 'i18next';
18
18
  import '../packages/core-app-api/src/routing/FlatRoutes.esm.js';
19
19
 
20
20
  const App = createExtension({
21
- namespace: "app",
22
21
  attachTo: { id: "root", input: "app" },
23
22
  inputs: {
24
23
  root: createExtensionInput([coreExtensionData.reactElement], {
@@ -1 +1 @@
1
- {"version":3,"file":"App.esm.js","sources":["../../src/extensions/App.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 React from 'react';\nimport {\n ExtensionBoundary,\n coreExtensionData,\n createExtension,\n createExtensionInput,\n} from '@backstage/frontend-plugin-api';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { ApiProvider } from '../../../../packages/core-app-api/src';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { AppThemeProvider } from '../../../../packages/core-app-api/src/app/AppThemeProvider';\n\nexport const App = createExtension({\n namespace: 'app',\n attachTo: { id: 'root', input: 'app' },\n inputs: {\n root: createExtensionInput([coreExtensionData.reactElement], {\n singleton: true,\n }),\n },\n output: [coreExtensionData.reactElement],\n factory: ({ node, apis, inputs }) => {\n return [\n coreExtensionData.reactElement(\n <ApiProvider apis={apis}>\n <AppThemeProvider>\n <ExtensionBoundary node={node}>\n {inputs.root.get(coreExtensionData.reactElement)}\n </ExtensionBoundary>\n </AppThemeProvider>\n </ApiProvider>,\n ),\n ];\n },\n});\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AA4BO,MAAM,MAAM,eAAgB,CAAA;AAAA,EACjC,SAAW,EAAA,KAAA;AAAA,EACX,QAAU,EAAA,EAAE,EAAI,EAAA,MAAA,EAAQ,OAAO,KAAM,EAAA;AAAA,EACrC,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA,oBAAA,CAAqB,CAAC,iBAAA,CAAkB,YAAY,CAAG,EAAA;AAAA,MAC3D,SAAW,EAAA,IAAA;AAAA,KACZ,CAAA;AAAA,GACH;AAAA,EACA,MAAA,EAAQ,CAAC,iBAAA,CAAkB,YAAY,CAAA;AAAA,EACvC,SAAS,CAAC,EAAE,IAAM,EAAA,IAAA,EAAM,QAAa,KAAA;AACnC,IAAO,OAAA;AAAA,MACL,iBAAkB,CAAA,YAAA;AAAA,wBACf,KAAA,CAAA,aAAA,CAAA,WAAA,EAAA,EAAY,IACX,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,wCACE,KAAA,CAAA,aAAA,CAAA,iBAAA,EAAA,EAAkB,IAChB,EAAA,EAAA,MAAA,CAAO,KAAK,GAAI,CAAA,iBAAA,CAAkB,YAAY,CACjD,CACF,CACF,CAAA;AAAA,OACF;AAAA,KACF,CAAA;AAAA,GACF;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"App.esm.js","sources":["../../src/extensions/App.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 React from 'react';\nimport {\n ExtensionBoundary,\n coreExtensionData,\n createExtension,\n createExtensionInput,\n} from '@backstage/frontend-plugin-api';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { ApiProvider } from '../../../../packages/core-app-api/src';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { AppThemeProvider } from '../../../../packages/core-app-api/src/app/AppThemeProvider';\n\nexport const App = createExtension({\n attachTo: { id: 'root', input: 'app' },\n inputs: {\n root: createExtensionInput([coreExtensionData.reactElement], {\n singleton: true,\n }),\n },\n output: [coreExtensionData.reactElement],\n factory: ({ node, apis, inputs }) => {\n return [\n coreExtensionData.reactElement(\n <ApiProvider apis={apis}>\n <AppThemeProvider>\n <ExtensionBoundary node={node}>\n {inputs.root.get(coreExtensionData.reactElement)}\n </ExtensionBoundary>\n </AppThemeProvider>\n </ApiProvider>,\n ),\n ];\n },\n});\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AA4BO,MAAM,MAAM,eAAgB,CAAA;AAAA,EACjC,QAAU,EAAA,EAAE,EAAI,EAAA,MAAA,EAAQ,OAAO,KAAM,EAAA;AAAA,EACrC,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA,oBAAA,CAAqB,CAAC,iBAAA,CAAkB,YAAY,CAAG,EAAA;AAAA,MAC3D,SAAW,EAAA,IAAA;AAAA,KACZ,CAAA;AAAA,GACH;AAAA,EACA,MAAA,EAAQ,CAAC,iBAAA,CAAkB,YAAY,CAAA;AAAA,EACvC,SAAS,CAAC,EAAE,IAAM,EAAA,IAAA,EAAM,QAAa,KAAA;AACnC,IAAO,OAAA;AAAA,MACL,iBAAkB,CAAA,YAAA;AAAA,wBACf,KAAA,CAAA,aAAA,CAAA,WAAA,EAAA,EAAY,IACX,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,wCACE,KAAA,CAAA,aAAA,CAAA,iBAAA,EAAA,EAAkB,IAChB,EAAA,EAAA,MAAA,CAAO,KAAK,GAAI,CAAA,iBAAA,CAAkB,YAAY,CACjD,CACF,CACF,CAAA;AAAA,OACF;AAAA,KACF,CAAA;AAAA,GACF;AACF,CAAC;;;;"}
@@ -3,7 +3,6 @@ import { createExtension, createExtensionInput, coreExtensionData } from '@backs
3
3
  import { SidebarPage } from '@backstage/core-components';
4
4
 
5
5
  const AppLayout = createExtension({
6
- namespace: "app",
7
6
  name: "layout",
8
7
  attachTo: { id: "app/root", input: "children" },
9
8
  inputs: {
@@ -1 +1 @@
1
- {"version":3,"file":"AppLayout.esm.js","sources":["../../src/extensions/AppLayout.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 React from 'react';\nimport {\n createExtension,\n coreExtensionData,\n createExtensionInput,\n} from '@backstage/frontend-plugin-api';\nimport { SidebarPage } from '@backstage/core-components';\n\nexport const AppLayout = createExtension({\n namespace: 'app',\n name: 'layout',\n attachTo: { id: 'app/root', input: 'children' },\n inputs: {\n nav: createExtensionInput([coreExtensionData.reactElement], {\n singleton: true,\n }),\n content: createExtensionInput([coreExtensionData.reactElement], {\n singleton: true,\n }),\n },\n output: [coreExtensionData.reactElement],\n factory: ({ inputs }) => [\n coreExtensionData.reactElement(\n <SidebarPage>\n {inputs.nav.get(coreExtensionData.reactElement)}\n {inputs.content.get(coreExtensionData.reactElement)}\n </SidebarPage>,\n ),\n ],\n});\n"],"names":[],"mappings":";;;;AAwBO,MAAM,YAAY,eAAgB,CAAA;AAAA,EACvC,SAAW,EAAA,KAAA;AAAA,EACX,IAAM,EAAA,QAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,UAAA,EAAY,OAAO,UAAW,EAAA;AAAA,EAC9C,MAAQ,EAAA;AAAA,IACN,GAAK,EAAA,oBAAA,CAAqB,CAAC,iBAAA,CAAkB,YAAY,CAAG,EAAA;AAAA,MAC1D,SAAW,EAAA,IAAA;AAAA,KACZ,CAAA;AAAA,IACD,OAAS,EAAA,oBAAA,CAAqB,CAAC,iBAAA,CAAkB,YAAY,CAAG,EAAA;AAAA,MAC9D,SAAW,EAAA,IAAA;AAAA,KACZ,CAAA;AAAA,GACH;AAAA,EACA,MAAA,EAAQ,CAAC,iBAAA,CAAkB,YAAY,CAAA;AAAA,EACvC,OAAS,EAAA,CAAC,EAAE,MAAA,EAAa,KAAA;AAAA,IACvB,iBAAkB,CAAA,YAAA;AAAA,sBACf,KAAA,CAAA,aAAA,CAAA,WAAA,EAAA,IAAA,EACE,MAAO,CAAA,GAAA,CAAI,GAAI,CAAA,iBAAA,CAAkB,YAAY,CAAA,EAC7C,MAAO,CAAA,OAAA,CAAQ,GAAI,CAAA,iBAAA,CAAkB,YAAY,CACpD,CAAA;AAAA,KACF;AAAA,GACF;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"AppLayout.esm.js","sources":["../../src/extensions/AppLayout.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 React from 'react';\nimport {\n createExtension,\n coreExtensionData,\n createExtensionInput,\n} from '@backstage/frontend-plugin-api';\nimport { SidebarPage } from '@backstage/core-components';\n\nexport const AppLayout = createExtension({\n name: 'layout',\n attachTo: { id: 'app/root', input: 'children' },\n inputs: {\n nav: createExtensionInput([coreExtensionData.reactElement], {\n singleton: true,\n }),\n content: createExtensionInput([coreExtensionData.reactElement], {\n singleton: true,\n }),\n },\n output: [coreExtensionData.reactElement],\n factory: ({ inputs }) => [\n coreExtensionData.reactElement(\n <SidebarPage>\n {inputs.nav.get(coreExtensionData.reactElement)}\n {inputs.content.get(coreExtensionData.reactElement)}\n </SidebarPage>,\n ),\n ],\n});\n"],"names":[],"mappings":";;;;AAwBO,MAAM,YAAY,eAAgB,CAAA;AAAA,EACvC,IAAM,EAAA,QAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,UAAA,EAAY,OAAO,UAAW,EAAA;AAAA,EAC9C,MAAQ,EAAA;AAAA,IACN,GAAK,EAAA,oBAAA,CAAqB,CAAC,iBAAA,CAAkB,YAAY,CAAG,EAAA;AAAA,MAC1D,SAAW,EAAA,IAAA;AAAA,KACZ,CAAA;AAAA,IACD,OAAS,EAAA,oBAAA,CAAqB,CAAC,iBAAA,CAAkB,YAAY,CAAG,EAAA;AAAA,MAC9D,SAAW,EAAA,IAAA;AAAA,KACZ,CAAA;AAAA,GACH;AAAA,EACA,MAAA,EAAQ,CAAC,iBAAA,CAAkB,YAAY,CAAA;AAAA,EACvC,OAAS,EAAA,CAAC,EAAE,MAAA,EAAa,KAAA;AAAA,IACvB,iBAAkB,CAAA,YAAA;AAAA,sBACf,KAAA,CAAA,aAAA,CAAA,WAAA,EAAA,IAAA,EACE,MAAO,CAAA,GAAA,CAAI,GAAI,CAAA,iBAAA,CAAkB,YAAY,CAAA,EAC7C,MAAO,CAAA,OAAA,CAAQ,GAAI,CAAA,iBAAA,CAAkB,YAAY,CACpD,CAAA;AAAA,KACF;AAAA,GACF;AACF,CAAC;;;;"}
@@ -33,7 +33,6 @@ const SidebarNavItem = (props) => {
33
33
  return /* @__PURE__ */ React.createElement(SidebarItem, { to: link(), icon: Icon, text: title });
34
34
  };
35
35
  const AppNav = createExtension({
36
- namespace: "app",
37
36
  name: "nav",
38
37
  attachTo: { id: "app/layout", input: "nav" },
39
38
  inputs: {
@@ -1 +1 @@
1
- {"version":3,"file":"AppNav.esm.js","sources":["../../src/extensions/AppNav.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 React from 'react';\nimport {\n createExtension,\n coreExtensionData,\n createExtensionInput,\n useRouteRef,\n NavItemBlueprint,\n NavLogoBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport { makeStyles } from '@material-ui/core/styles';\nimport {\n Sidebar,\n useSidebarOpenState,\n Link,\n sidebarConfig,\n SidebarDivider,\n SidebarItem,\n} from '@backstage/core-components';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport LogoIcon from '../../../../packages/app/src/components/Root/LogoIcon';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport LogoFull from '../../../../packages/app/src/components/Root/LogoFull';\n\nconst useSidebarLogoStyles = makeStyles({\n root: {\n width: sidebarConfig.drawerWidthClosed,\n height: 3 * sidebarConfig.logoHeight,\n display: 'flex',\n flexFlow: 'row nowrap',\n alignItems: 'center',\n marginBottom: -14,\n },\n link: {\n width: sidebarConfig.drawerWidthClosed,\n marginLeft: 24,\n },\n});\n\nconst SidebarLogo = (\n props: (typeof NavLogoBlueprint.dataRefs.logoElements)['T'],\n) => {\n const classes = useSidebarLogoStyles();\n const { isOpen } = useSidebarOpenState();\n\n return (\n <div className={classes.root}>\n <Link to=\"/\" underline=\"none\" className={classes.link} aria-label=\"Home\">\n {isOpen\n ? props?.logoFull ?? <LogoFull />\n : props?.logoIcon ?? <LogoIcon />}\n </Link>\n </div>\n );\n};\n\nconst SidebarNavItem = (\n props: (typeof NavItemBlueprint.dataRefs.target)['T'],\n) => {\n const { icon: Icon, title, routeRef } = props;\n const link = useRouteRef(routeRef);\n if (!link) {\n return null;\n }\n // TODO: Support opening modal, for example, the search one\n return <SidebarItem to={link()} icon={Icon} text={title} />;\n};\n\nexport const AppNav = createExtension({\n namespace: 'app',\n name: 'nav',\n attachTo: { id: 'app/layout', input: 'nav' },\n inputs: {\n items: createExtensionInput([NavItemBlueprint.dataRefs.target]),\n logos: createExtensionInput([NavLogoBlueprint.dataRefs.logoElements], {\n singleton: true,\n optional: true,\n }),\n },\n output: [coreExtensionData.reactElement],\n factory: ({ inputs }) => [\n coreExtensionData.reactElement(\n <Sidebar>\n <SidebarLogo\n {...inputs.logos?.get(NavLogoBlueprint.dataRefs.logoElements)}\n />\n <SidebarDivider />\n {inputs.items.map((item, index) => (\n <SidebarNavItem\n {...item.get(NavItemBlueprint.dataRefs.target)}\n key={index}\n />\n ))}\n </Sidebar>,\n ),\n ],\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AppNav.esm.js","sources":["../../src/extensions/AppNav.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 React from 'react';\nimport {\n createExtension,\n coreExtensionData,\n createExtensionInput,\n useRouteRef,\n NavItemBlueprint,\n NavLogoBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport { makeStyles } from '@material-ui/core/styles';\nimport {\n Sidebar,\n useSidebarOpenState,\n Link,\n sidebarConfig,\n SidebarDivider,\n SidebarItem,\n} from '@backstage/core-components';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport LogoIcon from '../../../../packages/app/src/components/Root/LogoIcon';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport LogoFull from '../../../../packages/app/src/components/Root/LogoFull';\n\nconst useSidebarLogoStyles = makeStyles({\n root: {\n width: sidebarConfig.drawerWidthClosed,\n height: 3 * sidebarConfig.logoHeight,\n display: 'flex',\n flexFlow: 'row nowrap',\n alignItems: 'center',\n marginBottom: -14,\n },\n link: {\n width: sidebarConfig.drawerWidthClosed,\n marginLeft: 24,\n },\n});\n\nconst SidebarLogo = (\n props: (typeof NavLogoBlueprint.dataRefs.logoElements)['T'],\n) => {\n const classes = useSidebarLogoStyles();\n const { isOpen } = useSidebarOpenState();\n\n return (\n <div className={classes.root}>\n <Link to=\"/\" underline=\"none\" className={classes.link} aria-label=\"Home\">\n {isOpen\n ? props?.logoFull ?? <LogoFull />\n : props?.logoIcon ?? <LogoIcon />}\n </Link>\n </div>\n );\n};\n\nconst SidebarNavItem = (\n props: (typeof NavItemBlueprint.dataRefs.target)['T'],\n) => {\n const { icon: Icon, title, routeRef } = props;\n const link = useRouteRef(routeRef);\n if (!link) {\n return null;\n }\n // TODO: Support opening modal, for example, the search one\n return <SidebarItem to={link()} icon={Icon} text={title} />;\n};\n\nexport const AppNav = createExtension({\n name: 'nav',\n attachTo: { id: 'app/layout', input: 'nav' },\n inputs: {\n items: createExtensionInput([NavItemBlueprint.dataRefs.target]),\n logos: createExtensionInput([NavLogoBlueprint.dataRefs.logoElements], {\n singleton: true,\n optional: true,\n }),\n },\n output: [coreExtensionData.reactElement],\n factory: ({ inputs }) => [\n coreExtensionData.reactElement(\n <Sidebar>\n <SidebarLogo\n {...inputs.logos?.get(NavLogoBlueprint.dataRefs.logoElements)}\n />\n <SidebarDivider />\n {inputs.items.map((item, index) => (\n <SidebarNavItem\n {...item.get(NavItemBlueprint.dataRefs.target)}\n key={index}\n />\n ))}\n </Sidebar>,\n ),\n ],\n});\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import React, { Fragment, useState } from 'react';
1
+ import React, { useState } from 'react';
2
2
  import { createExtension, createExtensionInput, RouterBlueprint, SignInPageBlueprint, coreExtensionData, AppRootWrapperBlueprint, discoveryApiRef, errorApiRef, fetchApiRef, routeResolutionApiRef } from '@backstage/frontend-plugin-api';
3
3
  import { identityApiRef, useApi, configApiRef } from '@backstage/core-plugin-api';
4
4
  import { isProtectedApp } from '../packages/core-app-api/src/app/isProtectedApp.esm.js';
@@ -7,7 +7,6 @@ import { RouteTracker } from '../packages/frontend-app-api/src/routing/RouteTrac
7
7
  import { getBasePath } from '../packages/frontend-app-api/src/routing/getBasePath.esm.js';
8
8
 
9
9
  const AppRoot = createExtension({
10
- namespace: "app",
11
10
  name: "root",
12
11
  attachTo: { id: "app", input: "root" },
13
12
  inputs: {
@@ -49,7 +48,9 @@ const AppRoot = createExtension({
49
48
  fetchApi
50
49
  });
51
50
  }
52
- let content = /* @__PURE__ */ React.createElement(React.Fragment, null, inputs.elements.map((el) => /* @__PURE__ */ React.createElement(Fragment, { key: el.node.spec.id }, el.get(coreExtensionData.reactElement))), inputs.children.get(coreExtensionData.reactElement));
51
+ let content = inputs.children.get(
52
+ coreExtensionData.reactElement
53
+ );
53
54
  for (const wrapper of inputs.wrappers) {
54
55
  const Component = wrapper.get(AppRootWrapperBlueprint.dataRefs.component);
55
56
  content = /* @__PURE__ */ React.createElement(Component, null, content);
@@ -64,6 +65,9 @@ const AppRoot = createExtension({
64
65
  ),
65
66
  RouterComponent: inputs.router?.get(
66
67
  RouterBlueprint.dataRefs.component
68
+ ),
69
+ extraElements: inputs.elements?.map(
70
+ (el) => el.get(coreExtensionData.reactElement)
67
71
  )
68
72
  },
69
73
  content
@@ -103,7 +107,8 @@ function AppRouter(props) {
103
107
  const {
104
108
  children,
105
109
  SignInPageComponent,
106
- RouterComponent = DefaultRouter
110
+ RouterComponent = DefaultRouter,
111
+ extraElements = []
107
112
  } = props;
108
113
  const configApi = useApi(configApiRef);
109
114
  const appIdentityProxy = toAppIdentityProxy(useApi(identityApiRef));
@@ -139,7 +144,7 @@ function AppRouter(props) {
139
144
  );
140
145
  return /* @__PURE__ */ React.createElement(RouterComponent, null, /* @__PURE__ */ React.createElement(RouteTracker, { routeObjects }), children);
141
146
  }
142
- return /* @__PURE__ */ React.createElement(RouterComponent, null, /* @__PURE__ */ React.createElement(RouteTracker, { routeObjects }), /* @__PURE__ */ React.createElement(
147
+ return /* @__PURE__ */ React.createElement(RouterComponent, null, ...extraElements, /* @__PURE__ */ React.createElement(RouteTracker, { routeObjects }), /* @__PURE__ */ React.createElement(
143
148
  SignInPageWrapper,
144
149
  {
145
150
  component: SignInPageComponent,
@@ -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 React, {\n ComponentType,\n Fragment,\n PropsWithChildren,\n ReactNode,\n useState,\n} from 'react';\nimport {\n AppRootWrapperBlueprint,\n RouterBlueprint,\n SignInPageBlueprint,\n coreExtensionData,\n discoveryApiRef,\n fetchApiRef,\n errorApiRef,\n createExtension,\n createExtensionInput,\n routeResolutionApiRef,\n} from '@backstage/frontend-plugin-api';\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 namespace: 'app',\n name: 'root',\n attachTo: { id: 'app', input: 'root' },\n inputs: {\n router: createExtensionInput([RouterBlueprint.dataRefs.component], {\n singleton: true,\n optional: true,\n }),\n signInPage: createExtensionInput([SignInPageBlueprint.dataRefs.component], {\n singleton: true,\n optional: 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 },\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: React.ReactNode = (\n <>\n {inputs.elements.map(el => (\n <Fragment key={el.node.spec.id}>\n {el.get(coreExtensionData.reactElement)}\n </Fragment>\n ))}\n {inputs.children.get(coreExtensionData.reactElement)}\n </>\n );\n\n for (const wrapper of inputs.wrappers) {\n const Component = wrapper.get(AppRootWrapperBlueprint.dataRefs.component);\n content = <Component>{content}</Component>;\n }\n\n return [\n coreExtensionData.reactElement(\n <AppRouter\n SignInPageComponent={inputs.signInPage?.get(\n SignInPageBlueprint.dataRefs.component,\n )}\n RouterComponent={inputs.router?.get(\n RouterBlueprint.dataRefs.component,\n )}\n >\n {content}\n </AppRouter>,\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?: ComponentType<PropsWithChildren<{}>>;\n}\n\nfunction DefaultRouter(props: PropsWithChildren<{}>) {\n const configApi = useApi(configApiRef);\n const basePath = getBasePath(configApi);\n return <BrowserRouter basename={basePath}>{props.children}</BrowserRouter>;\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 } = 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 <RouteTracker routeObjects={routeObjects} />\n {children}\n </RouterComponent>\n );\n }\n\n return (\n <RouterComponent>\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 React, {\n ComponentType,\n PropsWithChildren,\n ReactNode,\n useState,\n} from 'react';\nimport {\n AppRootWrapperBlueprint,\n RouterBlueprint,\n SignInPageBlueprint,\n coreExtensionData,\n discoveryApiRef,\n fetchApiRef,\n errorApiRef,\n createExtension,\n createExtensionInput,\n routeResolutionApiRef,\n} from '@backstage/frontend-plugin-api';\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 }),\n signInPage: createExtensionInput([SignInPageBlueprint.dataRefs.component], {\n singleton: true,\n optional: 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 },\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: React.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 content = <Component>{content}</Component>;\n }\n\n return [\n coreExtensionData.reactElement(\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 ),\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?: ComponentType<PropsWithChildren<{}>>;\n extraElements?: Array<React.JSX.Element>;\n}\n\nfunction DefaultRouter(props: PropsWithChildren<{}>) {\n const configApi = useApi(configApiRef);\n const basePath = getBasePath(configApi);\n return <BrowserRouter basename={basePath}>{props.children}</BrowserRouter>;\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 <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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"}
@@ -3,7 +3,6 @@ import { createExtension, createExtensionInput, coreExtensionData, useComponentR
3
3
  import { useRoutes } from 'react-router-dom';
4
4
 
5
5
  const AppRoutes = createExtension({
6
- namespace: "app",
7
6
  name: "routes",
8
7
  attachTo: { id: "app/layout", input: "content" },
9
8
  inputs: {
@@ -1 +1 @@
1
- {"version":3,"file":"AppRoutes.esm.js","sources":["../../src/extensions/AppRoutes.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 React from 'react';\nimport {\n createExtension,\n coreExtensionData,\n createExtensionInput,\n coreComponentRefs,\n useComponentRef,\n} from '@backstage/frontend-plugin-api';\nimport { useRoutes } from 'react-router-dom';\n\nexport const AppRoutes = createExtension({\n namespace: 'app',\n name: 'routes',\n attachTo: { id: 'app/layout', input: 'content' },\n inputs: {\n routes: createExtensionInput([\n coreExtensionData.routePath,\n coreExtensionData.routeRef.optional(),\n coreExtensionData.reactElement,\n ]),\n },\n output: [coreExtensionData.reactElement],\n factory({ inputs }) {\n const Routes = () => {\n const NotFoundErrorPage = useComponentRef(\n coreComponentRefs.notFoundErrorPage,\n );\n\n const element = useRoutes([\n ...inputs.routes.map(route => ({\n path: `${route.get(coreExtensionData.routePath)}/*`,\n element: route.get(coreExtensionData.reactElement),\n })),\n {\n path: '*',\n element: <NotFoundErrorPage />,\n },\n ]);\n\n return element;\n };\n\n return [coreExtensionData.reactElement(<Routes />)];\n },\n});\n"],"names":[],"mappings":";;;;AA0BO,MAAM,YAAY,eAAgB,CAAA;AAAA,EACvC,SAAW,EAAA,KAAA;AAAA,EACX,IAAM,EAAA,QAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,YAAA,EAAc,OAAO,SAAU,EAAA;AAAA,EAC/C,MAAQ,EAAA;AAAA,IACN,QAAQ,oBAAqB,CAAA;AAAA,MAC3B,iBAAkB,CAAA,SAAA;AAAA,MAClB,iBAAA,CAAkB,SAAS,QAAS,EAAA;AAAA,MACpC,iBAAkB,CAAA,YAAA;AAAA,KACnB,CAAA;AAAA,GACH;AAAA,EACA,MAAA,EAAQ,CAAC,iBAAA,CAAkB,YAAY,CAAA;AAAA,EACvC,OAAA,CAAQ,EAAE,MAAA,EAAU,EAAA;AAClB,IAAA,MAAM,SAAS,MAAM;AACnB,MAAA,MAAM,iBAAoB,GAAA,eAAA;AAAA,QACxB,iBAAkB,CAAA,iBAAA;AAAA,OACpB,CAAA;AAEA,MAAA,MAAM,UAAU,SAAU,CAAA;AAAA,QACxB,GAAG,MAAA,CAAO,MAAO,CAAA,GAAA,CAAI,CAAU,KAAA,MAAA;AAAA,UAC7B,MAAM,CAAG,EAAA,KAAA,CAAM,GAAI,CAAA,iBAAA,CAAkB,SAAS,CAAC,CAAA,EAAA,CAAA;AAAA,UAC/C,OAAS,EAAA,KAAA,CAAM,GAAI,CAAA,iBAAA,CAAkB,YAAY,CAAA;AAAA,SACjD,CAAA,CAAA;AAAA,QACF;AAAA,UACE,IAAM,EAAA,GAAA;AAAA,UACN,OAAA,sCAAU,iBAAkB,EAAA,IAAA,CAAA;AAAA,SAC9B;AAAA,OACD,CAAA,CAAA;AAED,MAAO,OAAA,OAAA,CAAA;AAAA,KACT,CAAA;AAEA,IAAA,OAAO,CAAC,iBAAkB,CAAA,YAAA,iBAAc,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,IAAO,CAAE,CAAC,CAAA,CAAA;AAAA,GACpD;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"AppRoutes.esm.js","sources":["../../src/extensions/AppRoutes.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 React from 'react';\nimport {\n createExtension,\n coreExtensionData,\n createExtensionInput,\n coreComponentRefs,\n useComponentRef,\n} from '@backstage/frontend-plugin-api';\nimport { useRoutes } from 'react-router-dom';\n\nexport const AppRoutes = createExtension({\n name: 'routes',\n attachTo: { id: 'app/layout', input: 'content' },\n inputs: {\n routes: createExtensionInput([\n coreExtensionData.routePath,\n coreExtensionData.routeRef.optional(),\n coreExtensionData.reactElement,\n ]),\n },\n output: [coreExtensionData.reactElement],\n factory({ inputs }) {\n const Routes = () => {\n const NotFoundErrorPage = useComponentRef(\n coreComponentRefs.notFoundErrorPage,\n );\n\n const element = useRoutes([\n ...inputs.routes.map(route => ({\n path: `${route.get(coreExtensionData.routePath)}/*`,\n element: route.get(coreExtensionData.reactElement),\n })),\n {\n path: '*',\n element: <NotFoundErrorPage />,\n },\n ]);\n\n return element;\n };\n\n return [coreExtensionData.reactElement(<Routes />)];\n },\n});\n"],"names":[],"mappings":";;;;AA0BO,MAAM,YAAY,eAAgB,CAAA;AAAA,EACvC,IAAM,EAAA,QAAA;AAAA,EACN,QAAU,EAAA,EAAE,EAAI,EAAA,YAAA,EAAc,OAAO,SAAU,EAAA;AAAA,EAC/C,MAAQ,EAAA;AAAA,IACN,QAAQ,oBAAqB,CAAA;AAAA,MAC3B,iBAAkB,CAAA,SAAA;AAAA,MAClB,iBAAA,CAAkB,SAAS,QAAS,EAAA;AAAA,MACpC,iBAAkB,CAAA,YAAA;AAAA,KACnB,CAAA;AAAA,GACH;AAAA,EACA,MAAA,EAAQ,CAAC,iBAAA,CAAkB,YAAY,CAAA;AAAA,EACvC,OAAA,CAAQ,EAAE,MAAA,EAAU,EAAA;AAClB,IAAA,MAAM,SAAS,MAAM;AACnB,MAAA,MAAM,iBAAoB,GAAA,eAAA;AAAA,QACxB,iBAAkB,CAAA,iBAAA;AAAA,OACpB,CAAA;AAEA,MAAA,MAAM,UAAU,SAAU,CAAA;AAAA,QACxB,GAAG,MAAA,CAAO,MAAO,CAAA,GAAA,CAAI,CAAU,KAAA,MAAA;AAAA,UAC7B,MAAM,CAAG,EAAA,KAAA,CAAM,GAAI,CAAA,iBAAA,CAAkB,SAAS,CAAC,CAAA,EAAA,CAAA;AAAA,UAC/C,OAAS,EAAA,KAAA,CAAM,GAAI,CAAA,iBAAA,CAAkB,YAAY,CAAA;AAAA,SACjD,CAAA,CAAA;AAAA,QACF;AAAA,UACE,IAAM,EAAA,GAAA;AAAA,UACN,OAAA,sCAAU,iBAAkB,EAAA,IAAA,CAAA;AAAA,SAC9B;AAAA,OACD,CAAA,CAAA;AAED,MAAO,OAAA,OAAA,CAAA;AAAA,KACT,CAAA;AAEA,IAAA,OAAO,CAAC,iBAAkB,CAAA,YAAA,iBAAc,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,IAAO,CAAE,CAAC,CAAA,CAAA;AAAA,GACpD;AACF,CAAC;;;;"}
@@ -25,6 +25,8 @@ import '@material-ui/icons/Person';
25
25
  import '@material-ui/icons/Warning';
26
26
  import '@material-ui/icons/Storage';
27
27
  import '@material-ui/icons/FeaturedPlayList';
28
+ import '@material-ui/icons/Star';
29
+ import '@material-ui/icons/StarBorder';
28
30
  import '@backstage/theme';
29
31
  import '@material-ui/icons/Brightness2';
30
32
  import '@material-ui/icons/WbSunny';
@@ -1 +1 @@
1
- {"version":3,"file":"components.esm.js","sources":["../../src/extensions/components.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 React from 'react';\n// TODO: Dependency on MUI should be removed from core packages\nimport Button from '@material-ui/core/Button';\n\nimport {\n createComponentExtension,\n coreComponentRefs,\n} from '@backstage/frontend-plugin-api';\nimport { ErrorPanel } from '@backstage/core-components';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { components as defaultComponents } from '../../../../packages/app-defaults/src/defaults';\n\nexport const DefaultProgressComponent = createComponentExtension({\n ref: coreComponentRefs.progress,\n loader: { sync: () => defaultComponents.Progress },\n});\n\nexport const DefaultNotFoundErrorPageComponent = createComponentExtension({\n ref: coreComponentRefs.notFoundErrorPage,\n loader: { sync: () => defaultComponents.NotFoundErrorPage },\n});\n\nexport const DefaultErrorBoundaryComponent = createComponentExtension({\n ref: coreComponentRefs.errorBoundaryFallback,\n loader: {\n sync: () => props => {\n const { plugin, error, resetError } = props;\n const title = `Error in ${plugin?.id}`;\n\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"],"names":["defaultComponents"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BO,MAAM,2BAA2B,wBAAyB,CAAA;AAAA,EAC/D,KAAK,iBAAkB,CAAA,QAAA;AAAA,EACvB,MAAQ,EAAA,EAAE,IAAM,EAAA,MAAMA,WAAkB,QAAS,EAAA;AACnD,CAAC,EAAA;AAEM,MAAM,oCAAoC,wBAAyB,CAAA;AAAA,EACxE,KAAK,iBAAkB,CAAA,iBAAA;AAAA,EACvB,MAAQ,EAAA,EAAE,IAAM,EAAA,MAAMA,WAAkB,iBAAkB,EAAA;AAC5D,CAAC,EAAA;AAEM,MAAM,gCAAgC,wBAAyB,CAAA;AAAA,EACpE,KAAK,iBAAkB,CAAA,qBAAA;AAAA,EACvB,MAAQ,EAAA;AAAA,IACN,IAAA,EAAM,MAAM,CAAS,KAAA,KAAA;AACnB,MAAA,MAAM,EAAE,MAAA,EAAQ,KAAO,EAAA,UAAA,EAAe,GAAA,KAAA,CAAA;AACtC,MAAM,MAAA,KAAA,GAAQ,CAAY,SAAA,EAAA,MAAA,EAAQ,EAAE,CAAA,CAAA,CAAA;AAEpC,MAAA,uBACG,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,KAAc,EAAA,KAAA,EAAc,eAAe,EAAA,IAAA,EAAA,kBACpD,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,EAAO,OAAQ,EAAA,UAAA,EAAW,OAAS,EAAA,UAAA,EAAA,EAAY,OAEhD,CACF,CAAA,CAAA;AAAA,KAEJ;AAAA,GACF;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"components.esm.js","sources":["../../src/extensions/components.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 React from 'react';\n// TODO: Dependency on MUI should be removed from core packages\nimport Button from '@material-ui/core/Button';\n\nimport {\n createComponentExtension,\n coreComponentRefs,\n} from '@backstage/frontend-plugin-api';\nimport { ErrorPanel } from '@backstage/core-components';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { components as defaultComponents } from '../../../../packages/app-defaults/src/defaults';\n\nexport const DefaultProgressComponent = createComponentExtension({\n ref: coreComponentRefs.progress,\n loader: { sync: () => defaultComponents.Progress },\n});\n\nexport const DefaultNotFoundErrorPageComponent = createComponentExtension({\n ref: coreComponentRefs.notFoundErrorPage,\n loader: { sync: () => defaultComponents.NotFoundErrorPage },\n});\n\nexport const DefaultErrorBoundaryComponent = createComponentExtension({\n ref: coreComponentRefs.errorBoundaryFallback,\n loader: {\n sync: () => props => {\n const { plugin, error, resetError } = props;\n const title = `Error in ${plugin?.id}`;\n\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"],"names":["defaultComponents"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BO,MAAM,2BAA2B,wBAAyB,CAAA;AAAA,EAC/D,KAAK,iBAAkB,CAAA,QAAA;AAAA,EACvB,MAAQ,EAAA,EAAE,IAAM,EAAA,MAAMA,WAAkB,QAAS,EAAA;AACnD,CAAC,EAAA;AAEM,MAAM,oCAAoC,wBAAyB,CAAA;AAAA,EACxE,KAAK,iBAAkB,CAAA,iBAAA;AAAA,EACvB,MAAQ,EAAA,EAAE,IAAM,EAAA,MAAMA,WAAkB,iBAAkB,EAAA;AAC5D,CAAC,EAAA;AAEM,MAAM,gCAAgC,wBAAyB,CAAA;AAAA,EACpE,KAAK,iBAAkB,CAAA,qBAAA;AAAA,EACvB,MAAQ,EAAA;AAAA,IACN,IAAA,EAAM,MAAM,CAAS,KAAA,KAAA;AACnB,MAAA,MAAM,EAAE,MAAA,EAAQ,KAAO,EAAA,UAAA,EAAe,GAAA,KAAA,CAAA;AACtC,MAAM,MAAA,KAAA,GAAQ,CAAY,SAAA,EAAA,MAAA,EAAQ,EAAE,CAAA,CAAA,CAAA;AAEpC,MAAA,uBACG,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,KAAc,EAAA,KAAA,EAAc,eAAe,EAAA,IAAA,EAAA,kBACpD,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,EAAO,OAAQ,EAAA,UAAA,EAAW,OAAS,EAAA,UAAA,EAAA,EAAY,OAEhD,CACF,CAAA,CAAA;AAAA,KAEJ;AAAA,GACF;AACF,CAAC;;;;"}
@@ -3,14 +3,12 @@ import { AppRootElementBlueprint } from '@backstage/frontend-plugin-api';
3
3
  import React from 'react';
4
4
 
5
5
  const oauthRequestDialogAppRootElement = AppRootElementBlueprint.make({
6
- namespace: "app",
7
6
  name: "oauth-request-dialog",
8
7
  params: {
9
8
  element: /* @__PURE__ */ React.createElement(OAuthRequestDialog, null)
10
9
  }
11
10
  });
12
11
  const alertDisplayAppRootElement = AppRootElementBlueprint.makeWithOverrides({
13
- namespace: "app",
14
12
  name: "alert-display",
15
13
  config: {
16
14
  schema: {
@@ -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 { AlertDisplay, OAuthRequestDialog } from '@backstage/core-components';\nimport { AppRootElementBlueprint } from '@backstage/frontend-plugin-api';\nimport React from 'react';\n\nexport const oauthRequestDialogAppRootElement = AppRootElementBlueprint.make({\n namespace: 'app',\n name: 'oauth-request-dialog',\n params: {\n element: <OAuthRequestDialog />,\n },\n});\n\nexport const alertDisplayAppRootElement =\n AppRootElementBlueprint.makeWithOverrides({\n namespace: 'app',\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: () => <AlertDisplay {...config} />,\n });\n },\n });\n"],"names":[],"mappings":";;;;AAoBa,MAAA,gCAAA,GAAmC,wBAAwB,IAAK,CAAA;AAAA,EAC3E,SAAW,EAAA,KAAA;AAAA,EACX,IAAM,EAAA,sBAAA;AAAA,EACN,MAAQ,EAAA;AAAA,IACN,OAAA,sCAAU,kBAAmB,EAAA,IAAA,CAAA;AAAA,GAC/B;AACF,CAAC,EAAA;AAEY,MAAA,0BAAA,GACX,wBAAwB,iBAAkB,CAAA;AAAA,EACxC,SAAW,EAAA,KAAA;AAAA,EACX,IAAM,EAAA,eAAA;AAAA,EACN,MAAQ,EAAA;AAAA,IACN,MAAQ,EAAA;AAAA,MACN,oBAAoB,CAAK,CAAA,KAAA,CAAA,CAAE,MAAO,EAAA,CAAE,QAAQ,GAAI,CAAA;AAAA,MAChD,YAAA,EAAc,CACZ,CAAA,KAAA,CAAA,CACG,MAAO,CAAA;AAAA,QACN,QAAA,EAAU,EAAE,IAAK,CAAA,CAAC,OAAO,QAAQ,CAAC,CAAE,CAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,QACjD,UAAA,EAAY,CAAE,CAAA,IAAA,CAAK,CAAC,MAAA,EAAQ,UAAU,OAAO,CAAC,CAAE,CAAA,OAAA,CAAQ,QAAQ,CAAA;AAAA,OACjE,CAAA,CACA,OAAQ,CAAA,EAAE,CAAA;AAAA,KACjB;AAAA,GACF;AAAA,EACA,OAAS,EAAA,CAAC,eAAiB,EAAA,EAAE,QAAa,KAAA;AACxC,IAAA,OAAO,eAAgB,CAAA;AAAA,MACrB,OAAS,EAAA,sBAAO,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA,EAAc,GAAG,MAAQ,EAAA,CAAA;AAAA,KAC1C,CAAA,CAAA;AAAA,GACH;AACF,CAAC;;;;"}
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 { AlertDisplay, OAuthRequestDialog } from '@backstage/core-components';\nimport { AppRootElementBlueprint } from '@backstage/frontend-plugin-api';\nimport React from 'react';\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: () => <AlertDisplay {...config} />,\n });\n },\n });\n"],"names":[],"mappings":";;;;AAoBa,MAAA,gCAAA,GAAmC,wBAAwB,IAAK,CAAA;AAAA,EAC3E,IAAM,EAAA,sBAAA;AAAA,EACN,MAAQ,EAAA;AAAA,IACN,OAAA,sCAAU,kBAAmB,EAAA,IAAA,CAAA;AAAA,GAC/B;AACF,CAAC,EAAA;AAEY,MAAA,0BAAA,GACX,wBAAwB,iBAAkB,CAAA;AAAA,EACxC,IAAM,EAAA,eAAA;AAAA,EACN,MAAQ,EAAA;AAAA,IACN,MAAQ,EAAA;AAAA,MACN,oBAAoB,CAAK,CAAA,KAAA,CAAA,CAAE,MAAO,EAAA,CAAE,QAAQ,GAAI,CAAA;AAAA,MAChD,YAAA,EAAc,CACZ,CAAA,KAAA,CAAA,CACG,MAAO,CAAA;AAAA,QACN,QAAA,EAAU,EAAE,IAAK,CAAA,CAAC,OAAO,QAAQ,CAAC,CAAE,CAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,QACjD,UAAA,EAAY,CAAE,CAAA,IAAA,CAAK,CAAC,MAAA,EAAQ,UAAU,OAAO,CAAC,CAAE,CAAA,OAAA,CAAQ,QAAQ,CAAA;AAAA,OACjE,CAAA,CACA,OAAQ,CAAA,EAAE,CAAA;AAAA,KACjB;AAAA,GACF;AAAA,EACA,OAAS,EAAA,CAAC,eAAiB,EAAA,EAAE,QAAa,KAAA;AACxC,IAAA,OAAO,eAAgB,CAAA;AAAA,MACrB,OAAS,EAAA,sBAAO,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA,EAAc,GAAG,MAAQ,EAAA,CAAA;AAAA,KAC1C,CAAA,CAAA;AAAA,GACH;AACF,CAAC;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,27 +1,10 @@
1
1
  /// <reference types="react" />
2
2
  import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
3
- import * as react from 'react';
4
3
  import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
4
+ import * as react from 'react';
5
5
 
6
6
  /** @public */
7
- declare const appPlugin: _backstage_frontend_plugin_api.BackstagePlugin<{}, {}, {
8
- [x: `component:app/${string}`]: _backstage_frontend_plugin_api.ExtensionDefinition<{
9
- config: {};
10
- configInput: {};
11
- output: _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<{
12
- ref: _backstage_frontend_plugin_api.ComponentRef;
13
- impl: react.ComponentType;
14
- }, "core.component.component", {}>;
15
- inputs: {
16
- [x: string]: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.AnyExtensionDataRef, {
17
- optional: boolean;
18
- singleton: boolean;
19
- }>;
20
- };
21
- kind: "component";
22
- namespace: string;
23
- name: string;
24
- }>;
7
+ declare const appPlugin: _backstage_frontend_plugin_api.FrontendPlugin<{}, {}, {
25
8
  app: _backstage_frontend_plugin_api.ExtensionDefinition<{
26
9
  config: {};
27
10
  configInput: {};
@@ -33,7 +16,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.BackstagePlugin<{}, {},
33
16
  }>;
34
17
  };
35
18
  kind: undefined;
36
- namespace: "app";
19
+ namespace: undefined;
37
20
  name: undefined;
38
21
  }>;
39
22
  "api:app/app-language": _backstage_frontend_plugin_api.ExtensionDefinition<{
@@ -60,7 +43,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.BackstagePlugin<{}, {},
60
43
  }>;
61
44
  };
62
45
  kind: undefined;
63
- namespace: "app";
46
+ namespace: undefined;
64
47
  name: "layout";
65
48
  }>;
66
49
  "app/nav": _backstage_frontend_plugin_api.ExtensionDefinition<{
@@ -85,7 +68,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.BackstagePlugin<{}, {},
85
68
  }>;
86
69
  };
87
70
  kind: undefined;
88
- namespace: "app";
71
+ namespace: undefined;
89
72
  name: "nav";
90
73
  }>;
91
74
  "app/root": _backstage_frontend_plugin_api.ExtensionDefinition<{
@@ -119,7 +102,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.BackstagePlugin<{}, {},
119
102
  }>;
120
103
  };
121
104
  kind: undefined;
122
- namespace: "app";
105
+ namespace: undefined;
123
106
  name: "root";
124
107
  }>;
125
108
  "app/routes": _backstage_frontend_plugin_api.ExtensionDefinition<{
@@ -135,7 +118,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.BackstagePlugin<{}, {},
135
118
  }>;
136
119
  };
137
120
  kind: undefined;
138
- namespace: "app";
121
+ namespace: undefined;
139
122
  name: "routes";
140
123
  }>;
141
124
  "api:app/app-theme": _backstage_frontend_plugin_api.ExtensionDefinition<{
@@ -154,7 +137,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.BackstagePlugin<{}, {},
154
137
  }>;
155
138
  "theme:app/light": _backstage_frontend_plugin_api.ExtensionDefinition<{
156
139
  kind: "theme";
157
- namespace: "app";
140
+ namespace: undefined;
158
141
  name: "light";
159
142
  config: {};
160
143
  configInput: {};
@@ -163,7 +146,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.BackstagePlugin<{}, {},
163
146
  }>;
164
147
  "theme:app/dark": _backstage_frontend_plugin_api.ExtensionDefinition<{
165
148
  kind: "theme";
166
- namespace: "app";
149
+ namespace: undefined;
167
150
  name: "dark";
168
151
  config: {};
169
152
  configInput: {};
@@ -230,7 +213,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.BackstagePlugin<{}, {},
230
213
  }>;
231
214
  "app-root-element:app/oauth-request-dialog": _backstage_frontend_plugin_api.ExtensionDefinition<{
232
215
  kind: "app-root-element";
233
- namespace: "app";
216
+ namespace: undefined;
234
217
  name: "oauth-request-dialog";
235
218
  config: {};
236
219
  configInput: {};
@@ -260,7 +243,7 @@ declare const appPlugin: _backstage_frontend_plugin_api.BackstagePlugin<{}, {},
260
243
  }>;
261
244
  };
262
245
  kind: "app-root-element";
263
- namespace: "app";
246
+ namespace: undefined;
264
247
  name: "alert-display";
265
248
  }>;
266
249
  "api:app/discovery": _backstage_frontend_plugin_api.ExtensionDefinition<{
@@ -19,6 +19,8 @@ import MuiPersonIcon from '@material-ui/icons/Person';
19
19
  import MuiWarningIcon from '@material-ui/icons/Warning';
20
20
  import MuiStorageIcon from '@material-ui/icons/Storage';
21
21
  import MuiFeaturedPlayListIcon from '@material-ui/icons/FeaturedPlayList';
22
+ import Star from '@material-ui/icons/Star';
23
+ import StarBorder from '@material-ui/icons/StarBorder';
22
24
 
23
25
  const icons = {
24
26
  brokenImage: MuiBrokenImageIcon,
@@ -44,7 +46,9 @@ const icons = {
44
46
  "kind:resource": MuiStorageIcon,
45
47
  "kind:template": MuiFeaturedPlayListIcon,
46
48
  user: MuiPersonIcon,
47
- warning: MuiWarningIcon
49
+ warning: MuiWarningIcon,
50
+ star: Star,
51
+ unstarred: StarBorder
48
52
  };
49
53
 
50
54
  export { icons };
@@ -1 +1 @@
1
- {"version":3,"file":"icons.esm.js","sources":["../../../../../../../packages/app-defaults/src/defaults/icons.tsx"],"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 { IconComponent } from '@backstage/core-plugin-api';\nimport MuiApartmentIcon from '@material-ui/icons/Apartment';\nimport MuiBrokenImageIcon from '@material-ui/icons/BrokenImage';\nimport MuiCategoryIcon from '@material-ui/icons/Category';\nimport MuiCreateNewFolderIcon from '@material-ui/icons/CreateNewFolder';\nimport MuiSubjectIcon from '@material-ui/icons/Subject';\nimport MuiSearchIcon from '@material-ui/icons/Search';\nimport MuiChatIcon from '@material-ui/icons/Chat';\nimport MuiDashboardIcon from '@material-ui/icons/Dashboard';\nimport MuiDocsIcon from '@material-ui/icons/Description';\nimport MuiEmailIcon from '@material-ui/icons/Email';\nimport MuiExtensionIcon from '@material-ui/icons/Extension';\nimport MuiGitHubIcon from '@material-ui/icons/GitHub';\nimport MuiHelpIcon from '@material-ui/icons/Help';\nimport MuiLocationOnIcon from '@material-ui/icons/LocationOn';\nimport MuiMemoryIcon from '@material-ui/icons/Memory';\nimport MuiMenuBookIcon from '@material-ui/icons/MenuBook';\nimport MuiPeopleIcon from '@material-ui/icons/People';\nimport MuiPersonIcon from '@material-ui/icons/Person';\nimport MuiWarningIcon from '@material-ui/icons/Warning';\nimport MuiStorageIcon from '@material-ui/icons/Storage';\nimport MuiFeaturedPlayListIcon from '@material-ui/icons/FeaturedPlayList';\n\nexport const icons = {\n brokenImage: MuiBrokenImageIcon as IconComponent,\n // To be confirmed: see https://github.com/backstage/backstage/issues/4970\n catalog: MuiMenuBookIcon as IconComponent,\n scaffolder: MuiCreateNewFolderIcon as IconComponent,\n techdocs: MuiSubjectIcon as IconComponent,\n search: MuiSearchIcon as IconComponent,\n chat: MuiChatIcon as IconComponent,\n dashboard: MuiDashboardIcon as IconComponent,\n docs: MuiDocsIcon as IconComponent,\n email: MuiEmailIcon as IconComponent,\n github: MuiGitHubIcon as IconComponent,\n group: MuiPeopleIcon as IconComponent,\n help: MuiHelpIcon as IconComponent,\n 'kind:api': MuiExtensionIcon as IconComponent,\n 'kind:component': MuiMemoryIcon as IconComponent,\n 'kind:domain': MuiApartmentIcon as IconComponent,\n 'kind:group': MuiPeopleIcon as IconComponent,\n 'kind:location': MuiLocationOnIcon as IconComponent,\n 'kind:system': MuiCategoryIcon as IconComponent,\n 'kind:user': MuiPersonIcon as IconComponent,\n 'kind:resource': MuiStorageIcon as IconComponent,\n 'kind:template': MuiFeaturedPlayListIcon as IconComponent,\n user: MuiPersonIcon as IconComponent,\n warning: MuiWarningIcon as IconComponent,\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuCO,MAAM,KAAQ,GAAA;AAAA,EACnB,WAAa,EAAA,kBAAA;AAAA;AAAA,EAEb,OAAS,EAAA,eAAA;AAAA,EACT,UAAY,EAAA,sBAAA;AAAA,EACZ,QAAU,EAAA,cAAA;AAAA,EACV,MAAQ,EAAA,aAAA;AAAA,EACR,IAAM,EAAA,WAAA;AAAA,EACN,SAAW,EAAA,gBAAA;AAAA,EACX,IAAM,EAAA,WAAA;AAAA,EACN,KAAO,EAAA,YAAA;AAAA,EACP,MAAQ,EAAA,aAAA;AAAA,EACR,KAAO,EAAA,aAAA;AAAA,EACP,IAAM,EAAA,WAAA;AAAA,EACN,UAAY,EAAA,gBAAA;AAAA,EACZ,gBAAkB,EAAA,aAAA;AAAA,EAClB,aAAe,EAAA,gBAAA;AAAA,EACf,YAAc,EAAA,aAAA;AAAA,EACd,eAAiB,EAAA,iBAAA;AAAA,EACjB,aAAe,EAAA,eAAA;AAAA,EACf,WAAa,EAAA,aAAA;AAAA,EACb,eAAiB,EAAA,cAAA;AAAA,EACjB,eAAiB,EAAA,uBAAA;AAAA,EACjB,IAAM,EAAA,aAAA;AAAA,EACN,OAAS,EAAA,cAAA;AACX;;;;"}
1
+ {"version":3,"file":"icons.esm.js","sources":["../../../../../../../packages/app-defaults/src/defaults/icons.tsx"],"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 { IconComponent } from '@backstage/core-plugin-api';\nimport MuiApartmentIcon from '@material-ui/icons/Apartment';\nimport MuiBrokenImageIcon from '@material-ui/icons/BrokenImage';\nimport MuiCategoryIcon from '@material-ui/icons/Category';\nimport MuiCreateNewFolderIcon from '@material-ui/icons/CreateNewFolder';\nimport MuiSubjectIcon from '@material-ui/icons/Subject';\nimport MuiSearchIcon from '@material-ui/icons/Search';\nimport MuiChatIcon from '@material-ui/icons/Chat';\nimport MuiDashboardIcon from '@material-ui/icons/Dashboard';\nimport MuiDocsIcon from '@material-ui/icons/Description';\nimport MuiEmailIcon from '@material-ui/icons/Email';\nimport MuiExtensionIcon from '@material-ui/icons/Extension';\nimport MuiGitHubIcon from '@material-ui/icons/GitHub';\nimport MuiHelpIcon from '@material-ui/icons/Help';\nimport MuiLocationOnIcon from '@material-ui/icons/LocationOn';\nimport MuiMemoryIcon from '@material-ui/icons/Memory';\nimport MuiMenuBookIcon from '@material-ui/icons/MenuBook';\nimport MuiPeopleIcon from '@material-ui/icons/People';\nimport MuiPersonIcon from '@material-ui/icons/Person';\nimport MuiWarningIcon from '@material-ui/icons/Warning';\nimport MuiStorageIcon from '@material-ui/icons/Storage';\nimport MuiFeaturedPlayListIcon from '@material-ui/icons/FeaturedPlayList';\nimport Star from '@material-ui/icons/Star';\nimport StarBorder from '@material-ui/icons/StarBorder';\n\nexport const icons = {\n brokenImage: MuiBrokenImageIcon as IconComponent,\n // To be confirmed: see https://github.com/backstage/backstage/issues/4970\n catalog: MuiMenuBookIcon as IconComponent,\n scaffolder: MuiCreateNewFolderIcon as IconComponent,\n techdocs: MuiSubjectIcon as IconComponent,\n search: MuiSearchIcon as IconComponent,\n chat: MuiChatIcon as IconComponent,\n dashboard: MuiDashboardIcon as IconComponent,\n docs: MuiDocsIcon as IconComponent,\n email: MuiEmailIcon as IconComponent,\n github: MuiGitHubIcon as IconComponent,\n group: MuiPeopleIcon as IconComponent,\n help: MuiHelpIcon as IconComponent,\n 'kind:api': MuiExtensionIcon as IconComponent,\n 'kind:component': MuiMemoryIcon as IconComponent,\n 'kind:domain': MuiApartmentIcon as IconComponent,\n 'kind:group': MuiPeopleIcon as IconComponent,\n 'kind:location': MuiLocationOnIcon as IconComponent,\n 'kind:system': MuiCategoryIcon as IconComponent,\n 'kind:user': MuiPersonIcon as IconComponent,\n 'kind:resource': MuiStorageIcon as IconComponent,\n 'kind:template': MuiFeaturedPlayListIcon as IconComponent,\n user: MuiPersonIcon as IconComponent,\n warning: MuiWarningIcon as IconComponent,\n star: Star as IconComponent,\n unstarred: StarBorder as IconComponent,\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAyCO,MAAM,KAAQ,GAAA;AAAA,EACnB,WAAa,EAAA,kBAAA;AAAA;AAAA,EAEb,OAAS,EAAA,eAAA;AAAA,EACT,UAAY,EAAA,sBAAA;AAAA,EACZ,QAAU,EAAA,cAAA;AAAA,EACV,MAAQ,EAAA,aAAA;AAAA,EACR,IAAM,EAAA,WAAA;AAAA,EACN,SAAW,EAAA,gBAAA;AAAA,EACX,IAAM,EAAA,WAAA;AAAA,EACN,KAAO,EAAA,YAAA;AAAA,EACP,MAAQ,EAAA,aAAA;AAAA,EACR,KAAO,EAAA,aAAA;AAAA,EACP,IAAM,EAAA,WAAA;AAAA,EACN,UAAY,EAAA,gBAAA;AAAA,EACZ,gBAAkB,EAAA,aAAA;AAAA,EAClB,aAAe,EAAA,gBAAA;AAAA,EACf,YAAc,EAAA,aAAA;AAAA,EACd,eAAiB,EAAA,iBAAA;AAAA,EACjB,aAAe,EAAA,eAAA;AAAA,EACf,WAAa,EAAA,aAAA;AAAA,EACb,eAAiB,EAAA,cAAA;AAAA,EACjB,eAAiB,EAAA,uBAAA;AAAA,EACjB,IAAM,EAAA,aAAA;AAAA,EACN,OAAS,EAAA,cAAA;AAAA,EACT,IAAM,EAAA,IAAA;AAAA,EACN,SAAW,EAAA,UAAA;AACb;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-app",
3
- "version": "0.1.0-next.0",
3
+ "version": "0.1.0-next.2",
4
4
  "main": "dist/index.esm.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -34,11 +34,11 @@
34
34
  "postpack": "backstage-cli package postpack"
35
35
  },
36
36
  "dependencies": {
37
- "@backstage/core-components": "^0.14.10",
38
- "@backstage/core-plugin-api": "^1.9.3",
39
- "@backstage/frontend-plugin-api": "^0.8.0-next.0",
40
- "@backstage/plugin-permission-react": "^0.4.25",
41
- "@backstage/theme": "^0.5.6",
37
+ "@backstage/core-components": "^0.14.11-next.1",
38
+ "@backstage/core-plugin-api": "^1.9.4-next.0",
39
+ "@backstage/frontend-plugin-api": "^0.8.0-next.2",
40
+ "@backstage/plugin-permission-react": "^0.4.26-next.0",
41
+ "@backstage/theme": "^0.5.7-next.0",
42
42
  "@material-ui/core": "^4.9.13",
43
43
  "@material-ui/icons": "^4.9.1",
44
44
  "@material-ui/lab": "^4.0.0-alpha.61",
@@ -50,11 +50,11 @@
50
50
  "react-router-dom": "6.0.0-beta.0 || ^6.3.0"
51
51
  },
52
52
  "devDependencies": {
53
- "@backstage/cli": "^0.27.1-next.0",
54
- "@backstage/dev-utils": "^1.0.38-next.0",
55
- "@backstage/frontend-test-utils": "^0.2.0-next.0",
53
+ "@backstage/cli": "^0.27.1-next.2",
54
+ "@backstage/dev-utils": "^1.1.0-next.2",
55
+ "@backstage/frontend-test-utils": "^0.2.0-next.2",
56
56
  "@testing-library/jest-dom": "^6.0.0",
57
- "@testing-library/react": "^15.0.0",
57
+ "@testing-library/react": "^16.0.0",
58
58
  "@testing-library/user-event": "^14.0.0",
59
59
  "msw": "^1.0.0",
60
60
  "react": "^16.13.1 || ^17.0.0 || ^18.0.0"