@backstage/plugin-app 0.4.6-next.2 → 0.4.7-next.0
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 +42 -0
- package/dist/extensions/AppNav.esm.js +4 -3
- package/dist/extensions/AppNav.esm.js.map +1 -1
- package/dist/extensions/legacyNavItem.esm.js +6 -0
- package/dist/extensions/legacyNavItem.esm.js.map +1 -0
- package/dist/plugins/app/package.json.esm.js +1 -1
- package/package.json +14 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,47 @@
|
|
|
1
1
|
# @backstage/plugin-app
|
|
2
2
|
|
|
3
|
+
## 0.4.7-next.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @backstage/core-components@0.18.11-next.0
|
|
9
|
+
- @backstage/integration-react@1.2.19-next.0
|
|
10
|
+
|
|
11
|
+
## 0.4.6
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- a345820: The `app/routes` redirect config now supports path parameter substitution in the `to` target. Named params (`:userId`) and splat params (`*`) captured by the `from` path are replaced in the `to` string before navigating, making it possible to express redirects like:
|
|
16
|
+
|
|
17
|
+
```yaml
|
|
18
|
+
app:
|
|
19
|
+
extensions:
|
|
20
|
+
- app/routes:
|
|
21
|
+
config:
|
|
22
|
+
redirects:
|
|
23
|
+
- from: /users/:userId
|
|
24
|
+
to: /profile/:userId
|
|
25
|
+
- from: /old-docs
|
|
26
|
+
to: /docs/*
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
- d1be10c: Migrated React Aria imports from individual packages (`@react-aria/toast`, `@react-aria/button`, `@react-stately/toast`) to the monopackages (`react-aria`, `react-stately`).
|
|
30
|
+
- e2d9831: Tightened React Aria dependency version ranges from `^` to `~` to prevent unintended minor version upgrades.
|
|
31
|
+
- f635139: Limited `@remixicon/react` dependency to versions below 4.9.0 due to a license change in that release.
|
|
32
|
+
- 2ba8c10: Following the removal of `NavItemBlueprint` in `@backstage/frontend-plugin-api`, the built-in app nav was updated to keep accepting legacy `nav-item` extensions so older plugins continue to work until they migrate.
|
|
33
|
+
- cad156e: Replaced old config schema values from existing extensions and blueprints.
|
|
34
|
+
- 085133f: The `zod` dependency has been bumped from `^3.25.76 || ^4.0.0` to `^4.0.0`, since `configSchema` requires the full Zod v4 package for JSON Schema support.
|
|
35
|
+
- Updated dependencies
|
|
36
|
+
- @backstage/core-components@0.18.10
|
|
37
|
+
- @backstage/ui@0.15.0
|
|
38
|
+
- @backstage/frontend-plugin-api@0.17.0
|
|
39
|
+
- @backstage/core-plugin-api@1.12.6
|
|
40
|
+
- @backstage/filter-predicates@0.1.3
|
|
41
|
+
- @backstage/plugin-app-react@0.2.3
|
|
42
|
+
- @backstage/integration-react@1.2.18
|
|
43
|
+
- @backstage/plugin-permission-react@0.5.1
|
|
44
|
+
|
|
3
45
|
## 0.4.6-next.2
|
|
4
46
|
|
|
5
47
|
### Patch Changes
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { createExtension, coreExtensionData,
|
|
2
|
+
import { createExtension, coreExtensionData, createExtensionInput, useApi, appTreeApiRef, routeResolutionApiRef } from '@backstage/frontend-plugin-api';
|
|
3
|
+
import { legacyNavItemTargetDataRef } from './legacyNavItem.esm.js';
|
|
3
4
|
import { NavContentBlueprint } from '@backstage/plugin-app-react';
|
|
4
5
|
import { Sidebar, SidebarItem } from '@backstage/core-components';
|
|
5
6
|
import { useMemo } from 'react';
|
|
@@ -157,7 +158,7 @@ const AppNav = createExtension({
|
|
|
157
158
|
name: "nav",
|
|
158
159
|
attachTo: { id: "app/layout", input: "nav" },
|
|
159
160
|
inputs: {
|
|
160
|
-
items: createExtensionInput([
|
|
161
|
+
items: createExtensionInput([legacyNavItemTargetDataRef]),
|
|
161
162
|
content: createExtensionInput([NavContentBlueprint.dataRefs.component], {
|
|
162
163
|
singleton: true,
|
|
163
164
|
optional: true,
|
|
@@ -172,7 +173,7 @@ const AppNav = createExtension({
|
|
|
172
173
|
NavContentRenderer,
|
|
173
174
|
{
|
|
174
175
|
legacyNavItems: inputs.items.map(
|
|
175
|
-
(item) => item.get(
|
|
176
|
+
(item) => item.get(legacyNavItemTargetDataRef)
|
|
176
177
|
),
|
|
177
178
|
Content
|
|
178
179
|
}
|
|
@@ -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 {\n createExtension,\n coreExtensionData,\n createExtensionInput,\n NavItemBlueprint,\n routeResolutionApiRef,\n appTreeApiRef,\n IconComponent,\n IconElement,\n RouteRef,\n RouteResolutionApi,\n useApi,\n} from '@backstage/frontend-plugin-api';\nimport {\n NavContentBlueprint,\n NavContentComponent,\n NavContentComponentProps,\n NavContentNavItem,\n NavContentNavItems,\n} from '@backstage/plugin-app-react';\nimport { Sidebar, SidebarItem } from '@backstage/core-components';\nimport { useMemo } from 'react';\n\nclass NavItemBag implements NavContentNavItems {\n readonly #items: NavContentNavItem[];\n readonly #index: Map<string, NavContentNavItem>;\n readonly #taken: Set<string>;\n #restItems: NavContentNavItem[] | undefined;\n\n constructor(items: NavContentNavItem[], taken?: Iterable<string>) {\n this.#items = items;\n this.#index = new Map(items.map(item => [item.node.spec.id, item]));\n this.#taken = new Set(taken);\n }\n\n take(id: string): NavContentNavItem | undefined {\n const item = this.#index.get(id);\n if (item && !this.#taken.has(id)) {\n this.#taken.add(id);\n if (this.#restItems) {\n const index = this.#restItems.findIndex(\n restItem => restItem.node.spec.id === id,\n );\n if (index !== -1) {\n this.#restItems.splice(index, 1);\n }\n }\n }\n return item;\n }\n\n rest(): NavContentNavItem[] {\n if (!this.#restItems) {\n this.#restItems = this.#items.filter(\n item => !this.#taken.has(item.node.spec.id),\n );\n }\n return this.#restItems;\n }\n\n clone(): NavContentNavItems {\n return new NavItemBag(this.#items, this.#taken);\n }\n\n withComponent(Component: (props: NavContentNavItem) => JSX.Element) {\n let renderedItems: JSX.Element[] | undefined;\n\n return {\n take: (id: string) => {\n const item = this.take(id);\n if (item && renderedItems) {\n const index = renderedItems.findIndex(\n renderedItem => renderedItem.key === item.node.spec.id,\n );\n if (index !== -1) {\n renderedItems.splice(index, 1);\n }\n }\n return item ? <Component key={item.node.spec.id} {...item} /> : null;\n },\n rest: (options?: { sortBy?: 'title' }) => {\n const items = this.rest();\n if (!renderedItems) {\n if (options?.sortBy === 'title') {\n items.sort((a, b) => a.title.localeCompare(b.title));\n }\n renderedItems = items.map(item => (\n <Component key={item.node.spec.id} {...item} />\n ));\n }\n return renderedItems;\n },\n };\n }\n}\n\nfunction DefaultNavContent(props: NavContentComponentProps) {\n const items = props.navItems.rest();\n return (\n <Sidebar>\n {items.map(item => (\n <SidebarItem\n to={item.href}\n icon={() => item.icon}\n text={item.title}\n key={item.node.spec.id}\n />\n ))}\n </Sidebar>\n );\n}\n\n// Tries to resolve a routeRef to a link path, returning undefined if it\n// can't be resolved (e.g. parameterized routes).\nfunction tryResolveLink(\n routeResolutionApi: RouteResolutionApi,\n routeRef: RouteRef,\n): string | undefined {\n try {\n const link = routeResolutionApi.resolve(routeRef);\n return link?.();\n } catch {\n return undefined;\n }\n}\n\n// Defers rendering until the app is fully initialized so that APIs like\n// RouteResolutionApi and AppTreeApi are available.\nfunction NavContentRenderer(props: {\n Content: NavContentComponent;\n legacyNavItems: Array<{\n title: string;\n icon: IconComponent;\n routeRef: RouteRef<undefined>;\n }>;\n}) {\n const appTreeApi = useApi(appTreeApiRef);\n const routeResolutionApi = useApi(routeResolutionApiRef);\n\n // Deprecated items: just resolve nav item routeRefs to paths, no page discovery.\n const legacyItems = useMemo(() => {\n return props.legacyNavItems.flatMap(item => {\n const link = routeResolutionApi.resolve(item.routeRef);\n if (!link) return [];\n return [\n {\n to: link(),\n text: item.title,\n icon: item.icon,\n title: item.title,\n routeRef: item.routeRef,\n },\n ];\n });\n }, [props.legacyNavItems, routeResolutionApi]);\n\n // New navItems: discover pages from the extension tree, merged with nav items.\n const navItems = useMemo(() => {\n const { tree } = appTreeApi.getTree();\n const routesNode = tree.nodes.get('app/routes');\n if (!routesNode) return new NavItemBag([]);\n\n // Index nav items by routeRef for matching against pages\n const navItemsByRouteRef = new Map<\n RouteRef,\n { title: string; icon: IconComponent }\n >(props.legacyNavItems.map(item => [item.routeRef, item]));\n\n const pageNodes = routesNode.edges.attachments.get('routes') ?? [];\n const items = pageNodes.flatMap((node): NavContentNavItem[] => {\n if (!node.instance || node.spec.disabled) {\n return [];\n }\n\n const routeRef = node.instance.getData(coreExtensionData.routeRef);\n if (!routeRef) {\n return [];\n }\n\n const matchingNavItem = navItemsByRouteRef.get(routeRef);\n\n // PageBlueprint resolves title as: config.title ?? params.title ?? plugin.title ?? pluginId\n // We want the priority: page (config/params) -> nav item -> plugin -> pluginId\n const resolvedTitle = node.instance.getData(coreExtensionData.title);\n const pluginTitle = node.spec.plugin.title;\n const pluginIcon = node.spec.plugin.icon;\n const pluginId = node.spec.plugin.pluginId;\n const hasExplicitPageTitle =\n resolvedTitle !== undefined &&\n resolvedTitle !== pluginTitle &&\n resolvedTitle !== pluginId;\n const title = hasExplicitPageTitle\n ? resolvedTitle\n : matchingNavItem?.title ?? pluginTitle ?? pluginId;\n\n // PageBlueprint resolves icon as: params.icon ?? plugin.icon\n // We want the priority: page (params) -> nav item -> plugin -> (excluded)\n const resolvedIcon = node.instance.getData(coreExtensionData.icon);\n const hasExplicitPageIcon = resolvedIcon && !node.spec.plugin.icon;\n const NavItemIcon = matchingNavItem?.icon;\n\n let icon: IconElement | undefined;\n if (hasExplicitPageIcon) {\n icon = resolvedIcon;\n } else if (NavItemIcon) {\n icon = <NavItemIcon />;\n } else if (resolvedIcon) {\n icon = resolvedIcon;\n } else if (pluginIcon) {\n icon = pluginIcon;\n }\n\n if (!title || !icon) {\n return [];\n }\n\n const to = tryResolveLink(routeResolutionApi, routeRef);\n if (!to) {\n return [];\n }\n\n return [{ node, href: to, title, icon, routeRef }];\n });\n\n return new NavItemBag(items);\n }, [appTreeApi, routeResolutionApi, props.legacyNavItems]);\n\n return <props.Content navItems={navItems} items={legacyItems} />;\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 content: createExtensionInput([NavContentBlueprint.dataRefs.component], {\n singleton: true,\n optional: true,\n internal: true,\n }),\n },\n output: [coreExtensionData.reactElement],\n *factory({ inputs }) {\n const Content =\n inputs.content?.get(NavContentBlueprint.dataRefs.component) ??\n DefaultNavContent;\n\n yield coreExtensionData.reactElement(\n <NavContentRenderer\n legacyNavItems={inputs.items.map(item =>\n item.get(NavItemBlueprint.dataRefs.target),\n )}\n Content={Content}\n />,\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 {\n createExtension,\n coreExtensionData,\n createExtensionInput,\n routeResolutionApiRef,\n appTreeApiRef,\n IconComponent,\n IconElement,\n RouteRef,\n RouteResolutionApi,\n useApi,\n} from '@backstage/frontend-plugin-api';\nimport { legacyNavItemTargetDataRef } from './legacyNavItem';\nimport {\n NavContentBlueprint,\n NavContentComponent,\n NavContentComponentProps,\n NavContentNavItem,\n NavContentNavItems,\n} from '@backstage/plugin-app-react';\nimport { Sidebar, SidebarItem } from '@backstage/core-components';\nimport { useMemo } from 'react';\n\nclass NavItemBag implements NavContentNavItems {\n readonly #items: NavContentNavItem[];\n readonly #index: Map<string, NavContentNavItem>;\n readonly #taken: Set<string>;\n #restItems: NavContentNavItem[] | undefined;\n\n constructor(items: NavContentNavItem[], taken?: Iterable<string>) {\n this.#items = items;\n this.#index = new Map(items.map(item => [item.node.spec.id, item]));\n this.#taken = new Set(taken);\n }\n\n take(id: string): NavContentNavItem | undefined {\n const item = this.#index.get(id);\n if (item && !this.#taken.has(id)) {\n this.#taken.add(id);\n if (this.#restItems) {\n const index = this.#restItems.findIndex(\n restItem => restItem.node.spec.id === id,\n );\n if (index !== -1) {\n this.#restItems.splice(index, 1);\n }\n }\n }\n return item;\n }\n\n rest(): NavContentNavItem[] {\n if (!this.#restItems) {\n this.#restItems = this.#items.filter(\n item => !this.#taken.has(item.node.spec.id),\n );\n }\n return this.#restItems;\n }\n\n clone(): NavContentNavItems {\n return new NavItemBag(this.#items, this.#taken);\n }\n\n withComponent(Component: (props: NavContentNavItem) => JSX.Element) {\n let renderedItems: JSX.Element[] | undefined;\n\n return {\n take: (id: string) => {\n const item = this.take(id);\n if (item && renderedItems) {\n const index = renderedItems.findIndex(\n renderedItem => renderedItem.key === item.node.spec.id,\n );\n if (index !== -1) {\n renderedItems.splice(index, 1);\n }\n }\n return item ? <Component key={item.node.spec.id} {...item} /> : null;\n },\n rest: (options?: { sortBy?: 'title' }) => {\n const items = this.rest();\n if (!renderedItems) {\n if (options?.sortBy === 'title') {\n items.sort((a, b) => a.title.localeCompare(b.title));\n }\n renderedItems = items.map(item => (\n <Component key={item.node.spec.id} {...item} />\n ));\n }\n return renderedItems;\n },\n };\n }\n}\n\nfunction DefaultNavContent(props: NavContentComponentProps) {\n const items = props.navItems.rest();\n return (\n <Sidebar>\n {items.map(item => (\n <SidebarItem\n to={item.href}\n icon={() => item.icon}\n text={item.title}\n key={item.node.spec.id}\n />\n ))}\n </Sidebar>\n );\n}\n\n// Tries to resolve a routeRef to a link path, returning undefined if it\n// can't be resolved (e.g. parameterized routes).\nfunction tryResolveLink(\n routeResolutionApi: RouteResolutionApi,\n routeRef: RouteRef,\n): string | undefined {\n try {\n const link = routeResolutionApi.resolve(routeRef);\n return link?.();\n } catch {\n return undefined;\n }\n}\n\n// Defers rendering until the app is fully initialized so that APIs like\n// RouteResolutionApi and AppTreeApi are available.\nfunction NavContentRenderer(props: {\n Content: NavContentComponent;\n legacyNavItems: Array<{\n title: string;\n icon: IconComponent;\n routeRef: RouteRef<undefined>;\n }>;\n}) {\n const appTreeApi = useApi(appTreeApiRef);\n const routeResolutionApi = useApi(routeResolutionApiRef);\n\n // Deprecated items: just resolve nav item routeRefs to paths, no page discovery.\n const legacyItems = useMemo(() => {\n return props.legacyNavItems.flatMap(item => {\n const link = routeResolutionApi.resolve(item.routeRef);\n if (!link) return [];\n return [\n {\n to: link(),\n text: item.title,\n icon: item.icon,\n title: item.title,\n routeRef: item.routeRef,\n },\n ];\n });\n }, [props.legacyNavItems, routeResolutionApi]);\n\n // New navItems: discover pages from the extension tree, merged with nav items.\n const navItems = useMemo(() => {\n const { tree } = appTreeApi.getTree();\n const routesNode = tree.nodes.get('app/routes');\n if (!routesNode) return new NavItemBag([]);\n\n // Index nav items by routeRef for matching against pages\n const navItemsByRouteRef = new Map<\n RouteRef,\n { title: string; icon: IconComponent }\n >(props.legacyNavItems.map(item => [item.routeRef, item]));\n\n const pageNodes = routesNode.edges.attachments.get('routes') ?? [];\n const items = pageNodes.flatMap((node): NavContentNavItem[] => {\n if (!node.instance || node.spec.disabled) {\n return [];\n }\n\n const routeRef = node.instance.getData(coreExtensionData.routeRef);\n if (!routeRef) {\n return [];\n }\n\n const matchingNavItem = navItemsByRouteRef.get(routeRef);\n\n // PageBlueprint resolves title as: config.title ?? params.title ?? plugin.title ?? pluginId\n // We want the priority: page (config/params) -> nav item -> plugin -> pluginId\n const resolvedTitle = node.instance.getData(coreExtensionData.title);\n const pluginTitle = node.spec.plugin.title;\n const pluginIcon = node.spec.plugin.icon;\n const pluginId = node.spec.plugin.pluginId;\n const hasExplicitPageTitle =\n resolvedTitle !== undefined &&\n resolvedTitle !== pluginTitle &&\n resolvedTitle !== pluginId;\n const title = hasExplicitPageTitle\n ? resolvedTitle\n : matchingNavItem?.title ?? pluginTitle ?? pluginId;\n\n // PageBlueprint resolves icon as: params.icon ?? plugin.icon\n // We want the priority: page (params) -> nav item -> plugin -> (excluded)\n const resolvedIcon = node.instance.getData(coreExtensionData.icon);\n const hasExplicitPageIcon = resolvedIcon && !node.spec.plugin.icon;\n const NavItemIcon = matchingNavItem?.icon;\n\n let icon: IconElement | undefined;\n if (hasExplicitPageIcon) {\n icon = resolvedIcon;\n } else if (NavItemIcon) {\n icon = <NavItemIcon />;\n } else if (resolvedIcon) {\n icon = resolvedIcon;\n } else if (pluginIcon) {\n icon = pluginIcon;\n }\n\n if (!title || !icon) {\n return [];\n }\n\n const to = tryResolveLink(routeResolutionApi, routeRef);\n if (!to) {\n return [];\n }\n\n return [{ node, href: to, title, icon, routeRef }];\n });\n\n return new NavItemBag(items);\n }, [appTreeApi, routeResolutionApi, props.legacyNavItems]);\n\n return <props.Content navItems={navItems} items={legacyItems} />;\n}\n\nexport const AppNav = createExtension({\n name: 'nav',\n attachTo: { id: 'app/layout', input: 'nav' },\n inputs: {\n items: createExtensionInput([legacyNavItemTargetDataRef]),\n content: createExtensionInput([NavContentBlueprint.dataRefs.component], {\n singleton: true,\n optional: true,\n internal: true,\n }),\n },\n output: [coreExtensionData.reactElement],\n *factory({ inputs }) {\n const Content =\n inputs.content?.get(NavContentBlueprint.dataRefs.component) ??\n DefaultNavContent;\n\n yield coreExtensionData.reactElement(\n <NavContentRenderer\n legacyNavItems={inputs.items.map(item =>\n item.get(legacyNavItemTargetDataRef),\n )}\n Content={Content}\n />,\n );\n },\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacyNavItem.esm.js","sources":["../../src/extensions/legacyNavItem.ts"],"sourcesContent":["/*\n * Copyright 2026 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 createExtensionDataRef,\n IconComponent,\n RouteRef,\n} from '@backstage/frontend-plugin-api';\n\n/**\n * @internal\n *\n * Data ref for legacy nav-item extensions. Kept for backward compatibility with\n * extensions created by older versions of the framework.\n */\nexport const legacyNavItemTargetDataRef = createExtensionDataRef<{\n title: string;\n icon: IconComponent;\n routeRef: RouteRef<undefined>;\n}>().with({ id: 'core.nav-item.target' });\n"],"names":[],"mappings":";;AA4BO,MAAM,6BAA6B,sBAAA,EAIvC,CAAE,KAAK,EAAE,EAAA,EAAI,wBAAwB;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-app",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.7-next.0",
|
|
4
4
|
"backstage": {
|
|
5
5
|
"role": "frontend-plugin",
|
|
6
6
|
"pluginId": "app",
|
|
@@ -63,16 +63,16 @@
|
|
|
63
63
|
"test": "backstage-cli package test"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"@backstage/core-components": "0.18.
|
|
67
|
-
"@backstage/core-plugin-api": "1.12.6
|
|
68
|
-
"@backstage/filter-predicates": "0.1.3
|
|
69
|
-
"@backstage/frontend-plugin-api": "0.17.0
|
|
70
|
-
"@backstage/integration-react": "1.2.
|
|
71
|
-
"@backstage/plugin-app-react": "0.2.3
|
|
72
|
-
"@backstage/plugin-permission-react": "0.5.1
|
|
66
|
+
"@backstage/core-components": "0.18.11-next.0",
|
|
67
|
+
"@backstage/core-plugin-api": "1.12.6",
|
|
68
|
+
"@backstage/filter-predicates": "0.1.3",
|
|
69
|
+
"@backstage/frontend-plugin-api": "0.17.0",
|
|
70
|
+
"@backstage/integration-react": "1.2.19-next.0",
|
|
71
|
+
"@backstage/plugin-app-react": "0.2.3",
|
|
72
|
+
"@backstage/plugin-permission-react": "0.5.1",
|
|
73
73
|
"@backstage/theme": "0.7.3",
|
|
74
74
|
"@backstage/types": "1.2.2",
|
|
75
|
-
"@backstage/ui": "0.15.0
|
|
75
|
+
"@backstage/ui": "0.15.0",
|
|
76
76
|
"@backstage/version-bridge": "1.0.12",
|
|
77
77
|
"@material-ui/core": "^4.9.13",
|
|
78
78
|
"@material-ui/icons": "^4.9.1",
|
|
@@ -87,11 +87,11 @@
|
|
|
87
87
|
"zod": "^4.0.0"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
|
-
"@backstage/cli": "0.36.
|
|
91
|
-
"@backstage/dev-utils": "1.1.
|
|
92
|
-
"@backstage/frontend-defaults": "0.5.
|
|
93
|
-
"@backstage/frontend-test-utils": "0.
|
|
94
|
-
"@backstage/test-utils": "1.7.18
|
|
90
|
+
"@backstage/cli": "0.36.3-next.0",
|
|
91
|
+
"@backstage/dev-utils": "1.1.24-next.0",
|
|
92
|
+
"@backstage/frontend-defaults": "0.5.3-next.0",
|
|
93
|
+
"@backstage/frontend-test-utils": "0.6.1-next.0",
|
|
94
|
+
"@backstage/test-utils": "1.7.18",
|
|
95
95
|
"@testing-library/jest-dom": "^6.0.0",
|
|
96
96
|
"@testing-library/react": "^16.0.0",
|
|
97
97
|
"@testing-library/user-event": "^14.0.0",
|