@backstage/plugin-home 0.9.2-next.1 → 0.9.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 +36 -0
- package/README.md +171 -22
- package/dist/alpha/DefaultHomePageLayout.esm.js +18 -0
- package/dist/alpha/DefaultHomePageLayout.esm.js.map +1 -0
- package/dist/alpha.d.ts +81 -10
- package/dist/alpha.esm.js +118 -27
- package/dist/alpha.esm.js.map +1 -1
- package/dist/api/VisitsApi.esm.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/package.json.esm.js +6 -3
- package/dist/package.json.esm.js.map +1 -1
- package/dist/translation.esm.js.map +1 -1
- package/package.json +19 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# @backstage/plugin-home
|
|
2
2
|
|
|
3
|
+
## 0.9.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 018ca87: Added `title` and `icon` to the plugin definition for the new frontend system.
|
|
8
|
+
- 90956a6: Support new frontend system in the homepage plugin
|
|
9
|
+
- a7e0d50: Updated `react-router-dom` peer dependency to `^6.30.2` and explicitly disabled v7 future flags to suppress deprecation warnings.
|
|
10
|
+
- 69d880e: Bump to latest zod to ensure it has the latest features
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @backstage/plugin-catalog-react@2.0.0
|
|
13
|
+
- @backstage/core-components@0.18.7
|
|
14
|
+
- @backstage/core-app-api@1.19.5
|
|
15
|
+
- @backstage/core-compat-api@0.5.8
|
|
16
|
+
- @backstage/theme@0.7.2
|
|
17
|
+
- @backstage/frontend-plugin-api@0.14.0
|
|
18
|
+
- @backstage/catalog-client@1.13.0
|
|
19
|
+
- @backstage/core-plugin-api@1.12.3
|
|
20
|
+
- @backstage/plugin-home-react@0.1.35
|
|
21
|
+
|
|
22
|
+
## 0.9.2-next.2
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- 90956a6: Support new frontend system in the homepage plugin
|
|
27
|
+
- a7e0d50: Prepare for React Router v7 migration by updating to v6.30.2 across all NFS packages and enabling v7 future flags. Convert routes from splat paths to parent/child structure with Outlet components.
|
|
28
|
+
- Updated dependencies
|
|
29
|
+
- @backstage/plugin-catalog-react@2.0.0-next.2
|
|
30
|
+
- @backstage/core-app-api@1.19.5-next.1
|
|
31
|
+
- @backstage/catalog-client@1.12.2-next.0
|
|
32
|
+
- @backstage/plugin-home-react@0.1.35-next.1
|
|
33
|
+
- @backstage/frontend-plugin-api@0.14.0-next.2
|
|
34
|
+
- @backstage/core-compat-api@0.5.8-next.2
|
|
35
|
+
- @backstage/core-components@0.18.7-next.2
|
|
36
|
+
- @backstage/core-plugin-api@1.12.3-next.1
|
|
37
|
+
- @backstage/theme@0.7.2-next.1
|
|
38
|
+
|
|
3
39
|
## 0.9.2-next.1
|
|
4
40
|
|
|
5
41
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ The Home plugin introduces a system for composing a Home Page for Backstage in o
|
|
|
4
4
|
|
|
5
5
|
For App Integrators, the system is designed to be composable to give total freedom in designing a Home Page that suits the needs of the organization. From the perspective of a Component Developer who wishes to contribute with building blocks to be included in Home Pages, there's a convenient interface for bundling the different parts and exporting them with both error boundary and lazy loading handled under the surface.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Installation
|
|
8
8
|
|
|
9
9
|
If you have a standalone app (you didn't clone this repo), then do
|
|
10
10
|
|
|
@@ -13,6 +13,170 @@ If you have a standalone app (you didn't clone this repo), then do
|
|
|
13
13
|
yarn --cwd packages/app add @backstage/plugin-home
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
## Getting started
|
|
17
|
+
|
|
18
|
+
The home plugin supports both the new frontend system and the legacy system.
|
|
19
|
+
|
|
20
|
+
### New Frontend System
|
|
21
|
+
|
|
22
|
+
If you're using Backstage's new frontend system, add the plugin to your app:
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
// packages/app/src/App.tsx
|
|
26
|
+
import homePlugin from '@backstage/plugin-home/alpha';
|
|
27
|
+
|
|
28
|
+
const app = createApp({
|
|
29
|
+
features: [
|
|
30
|
+
// ... other plugins
|
|
31
|
+
homePlugin,
|
|
32
|
+
// ... other plugins
|
|
33
|
+
],
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The plugin will automatically provide:
|
|
38
|
+
|
|
39
|
+
- A homepage at `/home` with customizable widget grid
|
|
40
|
+
- A "Home" navigation item in the sidebar
|
|
41
|
+
|
|
42
|
+
#### Creating Custom Homepage Layouts
|
|
43
|
+
|
|
44
|
+
Use the `HomePageLayoutBlueprint` from `@backstage/plugin-home-react/alpha` to
|
|
45
|
+
create custom homepage layouts. A layout receives the installed widgets and is
|
|
46
|
+
responsible for arranging them on the page. If no custom layout is installed, the
|
|
47
|
+
plugin provides a built-in default.
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { HomePageLayoutBlueprint } from '@backstage/plugin-home-react/alpha';
|
|
51
|
+
import { CustomHomepageGrid } from '@backstage/plugin-home';
|
|
52
|
+
import { Content, Header, Page } from '@backstage/core-components';
|
|
53
|
+
import { Fragment } from 'react';
|
|
54
|
+
|
|
55
|
+
const myHomePageLayout = HomePageLayoutBlueprint.make({
|
|
56
|
+
params: {
|
|
57
|
+
loader: async () =>
|
|
58
|
+
function MyHomePageLayout({ widgets }) {
|
|
59
|
+
return (
|
|
60
|
+
<Page themeId="home">
|
|
61
|
+
<Header title="Welcome" />
|
|
62
|
+
<Content>
|
|
63
|
+
<CustomHomepageGrid>
|
|
64
|
+
{widgets.map((widget, index) => (
|
|
65
|
+
<Fragment key={widget.name ?? index}>
|
|
66
|
+
{widget.component}
|
|
67
|
+
</Fragment>
|
|
68
|
+
))}
|
|
69
|
+
</CustomHomepageGrid>
|
|
70
|
+
</Content>
|
|
71
|
+
</Page>
|
|
72
|
+
);
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Then register the layout in a frontend module:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { createFrontendModule } from '@backstage/frontend-plugin-api';
|
|
82
|
+
|
|
83
|
+
const homeModule = createFrontendModule({
|
|
84
|
+
pluginId: 'home',
|
|
85
|
+
extensions: [myHomePageLayout],
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### Visit Tracking (Optional)
|
|
90
|
+
|
|
91
|
+
Visit tracking is an **optional feature** that must be explicitly enabled. When enabled, it provides intelligent storage fallbacks:
|
|
92
|
+
|
|
93
|
+
**Enabling Visit Tracking:**
|
|
94
|
+
|
|
95
|
+
Add the following to your `app-config.yaml`:
|
|
96
|
+
|
|
97
|
+
```yaml
|
|
98
|
+
app:
|
|
99
|
+
extensions:
|
|
100
|
+
# Enable visit tracking API (disabled by default)
|
|
101
|
+
- api:home/visits: true
|
|
102
|
+
# Enable visit listener (disabled by default)
|
|
103
|
+
- app-root-element:home/visit-listener: true
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Storage Strategy (when enabled):**
|
|
107
|
+
|
|
108
|
+
1. **Custom Storage API**: If you have `storageApiRef` configured (like database-backed `UserSettingsStorage`), visit data uses your custom storage
|
|
109
|
+
2. **Browser Local Storage Fallback**: If no custom storage is configured, automatically falls back to browser local storage
|
|
110
|
+
|
|
111
|
+
**Note**: Visit tracking extensions are disabled by default to give users control over data collection and storage.
|
|
112
|
+
|
|
113
|
+
## Creating Homepage Widgets
|
|
114
|
+
|
|
115
|
+
Homepage widgets are React components that can be added to customizable home pages. The **key difference** between the new frontend system and legacy system is how these widget components are **registered and exported**:
|
|
116
|
+
|
|
117
|
+
- **New Frontend System**: Use `HomePageWidgetBlueprint` to register widgets as extensions
|
|
118
|
+
- **Legacy System**: Use `createCardExtension` to export widgets as card components
|
|
119
|
+
|
|
120
|
+
### New Frontend System
|
|
121
|
+
|
|
122
|
+
Create widgets using the `HomePageWidgetBlueprint`:
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import { HomePageWidgetBlueprint } from '@backstage/plugin-home-react/alpha';
|
|
126
|
+
|
|
127
|
+
const myWidget = HomePageWidgetBlueprint.make({
|
|
128
|
+
name: 'my-widget',
|
|
129
|
+
params: {
|
|
130
|
+
name: 'MyWidget',
|
|
131
|
+
title: 'My Custom Widget',
|
|
132
|
+
description: 'A custom widget for the homepage',
|
|
133
|
+
components: () =>
|
|
134
|
+
import('./MyWidgetComponent').then(m => ({
|
|
135
|
+
Content: m.Content,
|
|
136
|
+
})),
|
|
137
|
+
layout: {
|
|
138
|
+
height: { minRows: 4 },
|
|
139
|
+
width: { minColumns: 3 },
|
|
140
|
+
},
|
|
141
|
+
settings: {
|
|
142
|
+
schema: {
|
|
143
|
+
title: 'Widget Settings',
|
|
144
|
+
type: 'object',
|
|
145
|
+
properties: {
|
|
146
|
+
color: {
|
|
147
|
+
title: 'Color',
|
|
148
|
+
type: 'string',
|
|
149
|
+
default: 'blue',
|
|
150
|
+
enum: ['blue', 'red', 'green'],
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
> **Example**: See [dev/index.tsx](dev/index.tsx) for a comprehensive example of creating multiple homepage widgets and layouts using the new frontend system.
|
|
160
|
+
|
|
161
|
+
### Legacy System - Widget Registration
|
|
162
|
+
|
|
163
|
+
In the legacy system, use the `createCardExtension` helper to create homepage widgets:
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
import { createCardExtension } from '@backstage/plugin-home-react';
|
|
167
|
+
|
|
168
|
+
export const MyWidget = homePlugin.provide(
|
|
169
|
+
createCardExtension<{ defaultCategory?: 'programming' | 'any' }>({
|
|
170
|
+
title: 'My Custom Widget',
|
|
171
|
+
components: () => import('./homePageComponents/MyWidget'),
|
|
172
|
+
}),
|
|
173
|
+
);
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The `createCardExtension` provides error boundary and lazy loading, and accepts generics for custom props that App Integrators can configure.
|
|
177
|
+
|
|
178
|
+
## Legacy System Setup
|
|
179
|
+
|
|
16
180
|
### Setting up the Home Page
|
|
17
181
|
|
|
18
182
|
1. Create a Home Page Component that will be used for composition.
|
|
@@ -40,28 +204,13 @@ import { homePage } from './components/home/HomePage';
|
|
|
40
204
|
// ...
|
|
41
205
|
```
|
|
42
206
|
|
|
43
|
-
### Creating Components
|
|
44
|
-
|
|
45
|
-
The Home Page can be composed with regular React components, so there's no magic in creating components to be used for composition 🪄 🎩 . However, in order to assure that your component fits into a diverse set of Home Pages, there's an extension creator for this purpose, that creates a Card-based layout, for consistency between components (read more about extensions [here](https://backstage.io/docs/plugins/composability#extensions)). The extension creator requires two fields: `title` and `components`. The `components` field is expected to be an asynchronous import that should at least contain a `Content` field. Additionally, you can optionally provide `settings`, `actions` and `contextProvider` as well. These parts will be combined to create a card, where the `content`, `actions` and `settings` will be wrapped within the `contextProvider` in order to be able to access to context and effectively communicate with one another.
|
|
46
|
-
|
|
47
|
-
Finally, the `createCardExtension` also accepts a generic, such that Component Developers can indicate to App Integrators what custom props their component will accept, such as the example below where the default category of the random jokes can be set.
|
|
48
|
-
|
|
49
|
-
```tsx
|
|
50
|
-
import { createCardExtension } from '@backstage/plugin-home-react';
|
|
51
|
-
|
|
52
|
-
export const RandomJokeHomePageComponent = homePlugin.provide(
|
|
53
|
-
createCardExtension<{ defaultCategory?: 'programming' | 'any' }>({
|
|
54
|
-
title: 'Random Joke',
|
|
55
|
-
components: () => import('./homePageComponents/RandomJoke'),
|
|
56
|
-
}),
|
|
57
|
-
);
|
|
58
|
-
```
|
|
207
|
+
### Creating Components (Legacy)
|
|
59
208
|
|
|
60
|
-
In
|
|
209
|
+
In the legacy system, homepage components can be regular React components or wrapped with `createCardExtension` for additional features like error boundaries and lazy loading. Components created with `createCardExtension` are exported as card components that can be composed into homepage layouts.
|
|
61
210
|
|
|
62
|
-
### Composing a Home Page
|
|
211
|
+
### Composing a Home Page (Legacy)
|
|
63
212
|
|
|
64
|
-
|
|
213
|
+
In the legacy system, composing a Home Page is done by creating regular React components. Components created with `createCardExtension` are rendered like so:
|
|
65
214
|
|
|
66
215
|
```tsx
|
|
67
216
|
import Grid from '@material-ui/core/Grid';
|
|
@@ -293,7 +442,7 @@ export const apis: AnyApiFactory[] = [
|
|
|
293
442
|
VisitsStorageApi.create({ storageApi, identityApi }),
|
|
294
443
|
}),
|
|
295
444
|
|
|
296
|
-
// Or a
|
|
445
|
+
// Or a local storage data implementation, relies on WebStorage implementation of storageApi
|
|
297
446
|
createApiFactory({
|
|
298
447
|
api: visitsApiRef,
|
|
299
448
|
deps: {
|
|
@@ -543,4 +692,4 @@ Additionally, the API is at a very early state, so contributing additional use c
|
|
|
543
692
|
### Homepage Templates
|
|
544
693
|
|
|
545
694
|
We are hoping that we together can build up a collection of Homepage templates. We therefore put together a place where we can collect all the templates for the Home Plugin in the [storybook](https://backstage.io/storybook/?path=/story/plugins-home-templates).
|
|
546
|
-
If you would like to contribute with a template, start by taking a look at the [DefaultTemplate storybook example](/packages/app/src/components/home/templates/DefaultTemplate.stories.tsx) or [CustomizableTemplate storybook example](/packages/app/src/components/home/templates/CustomizableTemplate.stories.tsx) to create your own, and then open a PR with your suggestion.
|
|
695
|
+
If you would like to contribute with a template, start by taking a look at the [DefaultTemplate storybook example](/packages/app-legacy/src/components/home/templates/DefaultTemplate.stories.tsx) or [CustomizableTemplate storybook example](/packages/app-legacy/src/components/home/templates/CustomizableTemplate.stories.tsx) to create your own, and then open a PR with your suggestion.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Fragment } from 'react';
|
|
3
|
+
import { Content } from '@backstage/core-components';
|
|
4
|
+
import 'react-router-dom';
|
|
5
|
+
import { CustomHomepageGrid } from '../components/CustomHomepage/CustomHomepageGrid.esm.js';
|
|
6
|
+
import '@backstage/core-app-api';
|
|
7
|
+
import '../api/VisitsApi.esm.js';
|
|
8
|
+
import '@backstage/core-plugin-api';
|
|
9
|
+
import '@backstage/catalog-model';
|
|
10
|
+
import '../components/VisitList/Context.esm.js';
|
|
11
|
+
|
|
12
|
+
function DefaultHomePageLayout(props) {
|
|
13
|
+
const { widgets } = props;
|
|
14
|
+
return /* @__PURE__ */ jsx(Content, { children: /* @__PURE__ */ jsx(CustomHomepageGrid, { children: widgets.map((widget, index) => /* @__PURE__ */ jsx(Fragment, { children: widget.component }, widget.name ?? index)) }) });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { DefaultHomePageLayout };
|
|
18
|
+
//# sourceMappingURL=DefaultHomePageLayout.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DefaultHomePageLayout.esm.js","sources":["../../src/alpha/DefaultHomePageLayout.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Fragment } from 'react';\nimport { Content } from '@backstage/core-components';\nimport type { HomePageLayoutProps } from '@backstage/plugin-home-react/alpha';\nimport { CustomHomepageGrid } from '../components';\n\n/**\n * The default home page layout component.\n *\n * Renders widgets inside a `<CustomHomepageGrid/>` wrapped in `<Content/>`.\n * This is used when no custom layout extension is installed.\n */\nexport function DefaultHomePageLayout(props: HomePageLayoutProps) {\n const { widgets } = props;\n return (\n <Content>\n <CustomHomepageGrid>\n {widgets.map((widget, index) => (\n <Fragment key={widget.name ?? index}>{widget.component}</Fragment>\n ))}\n </CustomHomepageGrid>\n </Content>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;AA2BO,SAAS,sBAAsB,KAAA,EAA4B;AAChE,EAAA,MAAM,EAAE,SAAQ,GAAI,KAAA;AACpB,EAAA,2BACG,OAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,sBACE,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,EAAQ,KAAA,qBACpB,GAAA,CAAC,QAAA,EAAA,EAAqC,iBAAO,SAAA,EAAA,EAA9B,MAAA,CAAO,QAAQ,KAAyB,CACxD,GACH,CAAA,EACF,CAAA;AAEJ;;;;"}
|
package/dist/alpha.d.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
import * as _backstage_plugin_home_react_alpha from '@backstage/plugin-home-react/alpha';
|
|
2
|
+
import { HomePageLayoutProps } from '@backstage/plugin-home-react/alpha';
|
|
1
3
|
import * as react from 'react';
|
|
2
4
|
import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
|
|
3
5
|
|
|
4
6
|
/**
|
|
7
|
+
* Translation reference for the home plugin.
|
|
8
|
+
* Contains localized text strings for home page components and widgets.
|
|
9
|
+
*
|
|
5
10
|
* @alpha
|
|
6
11
|
*/
|
|
7
12
|
declare const homeTranslationRef: _backstage_frontend_plugin_api.TranslationRef<"home", {
|
|
@@ -34,10 +39,11 @@ declare const homeTranslationRef: _backstage_frontend_plugin_api.TranslationRef<
|
|
|
34
39
|
}>;
|
|
35
40
|
|
|
36
41
|
/**
|
|
37
|
-
*
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
* Home plugin for the new frontend system.
|
|
43
|
+
*
|
|
44
|
+
* Provides core homepage functionality with optional visit tracking extensions.
|
|
45
|
+
* Visit tracking extensions are disabled by default and can be enabled via app-config.yaml.
|
|
46
|
+
*
|
|
41
47
|
* @alpha
|
|
42
48
|
*/
|
|
43
49
|
declare const _default: _backstage_frontend_plugin_api.OverridableFrontendPlugin<{
|
|
@@ -63,25 +69,87 @@ declare const _default: _backstage_frontend_plugin_api.OverridableFrontendPlugin
|
|
|
63
69
|
element: JSX.Element;
|
|
64
70
|
};
|
|
65
71
|
}>;
|
|
72
|
+
"home-page-widget:home/random-joke": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
73
|
+
kind: "home-page-widget";
|
|
74
|
+
name: "random-joke";
|
|
75
|
+
config: {};
|
|
76
|
+
configInput: {};
|
|
77
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_plugin_home_react_alpha.HomePageWidgetData, "home.widget.data", {}>;
|
|
78
|
+
inputs: {};
|
|
79
|
+
params: _backstage_plugin_home_react_alpha.HomePageWidgetBlueprintParams;
|
|
80
|
+
}>;
|
|
81
|
+
"home-page-widget:home/starred-entities": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
82
|
+
kind: "home-page-widget";
|
|
83
|
+
name: "starred-entities";
|
|
84
|
+
config: {};
|
|
85
|
+
configInput: {};
|
|
86
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_plugin_home_react_alpha.HomePageWidgetData, "home.widget.data", {}>;
|
|
87
|
+
inputs: {};
|
|
88
|
+
params: _backstage_plugin_home_react_alpha.HomePageWidgetBlueprintParams;
|
|
89
|
+
}>;
|
|
90
|
+
"home-page-widget:home/toolkit": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
91
|
+
kind: "home-page-widget";
|
|
92
|
+
name: "toolkit";
|
|
93
|
+
config: {};
|
|
94
|
+
configInput: {};
|
|
95
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_plugin_home_react_alpha.HomePageWidgetData, "home.widget.data", {}>;
|
|
96
|
+
inputs: {};
|
|
97
|
+
params: _backstage_plugin_home_react_alpha.HomePageWidgetBlueprintParams;
|
|
98
|
+
}>;
|
|
99
|
+
"nav-item:home": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
100
|
+
kind: "nav-item";
|
|
101
|
+
name: undefined;
|
|
102
|
+
config: {};
|
|
103
|
+
configInput: {};
|
|
104
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<{
|
|
105
|
+
title: string;
|
|
106
|
+
icon: _backstage_frontend_plugin_api.IconComponent;
|
|
107
|
+
routeRef: _backstage_frontend_plugin_api.RouteRef<undefined>;
|
|
108
|
+
}, "core.nav-item.target", {}>;
|
|
109
|
+
inputs: {};
|
|
110
|
+
params: {
|
|
111
|
+
title: string;
|
|
112
|
+
icon: _backstage_frontend_plugin_api.IconComponent;
|
|
113
|
+
routeRef: _backstage_frontend_plugin_api.RouteRef<undefined>;
|
|
114
|
+
};
|
|
115
|
+
}>;
|
|
66
116
|
"page:home": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
67
117
|
config: {
|
|
68
118
|
path: string | undefined;
|
|
119
|
+
title: string | undefined;
|
|
69
120
|
};
|
|
70
121
|
configInput: {
|
|
122
|
+
title?: string | undefined;
|
|
71
123
|
path?: string | undefined;
|
|
72
124
|
};
|
|
73
|
-
output: _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<
|
|
125
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
|
|
126
|
+
optional: true;
|
|
127
|
+
}> | _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.title", {
|
|
128
|
+
optional: true;
|
|
129
|
+
}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.IconElement, "core.icon", {
|
|
74
130
|
optional: true;
|
|
75
131
|
}>;
|
|
76
132
|
inputs: {
|
|
77
|
-
|
|
133
|
+
pages: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
|
|
134
|
+
optional: true;
|
|
135
|
+
}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<string, "core.title", {
|
|
78
136
|
optional: true;
|
|
79
|
-
}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<
|
|
137
|
+
}> | _backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_frontend_plugin_api.IconElement, "core.icon", {
|
|
80
138
|
optional: true;
|
|
81
139
|
}>, {
|
|
140
|
+
singleton: false;
|
|
141
|
+
optional: false;
|
|
142
|
+
internal: false;
|
|
143
|
+
}>;
|
|
144
|
+
widgets: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<_backstage_plugin_home_react_alpha.HomePageWidgetData, "home.widget.data", {}>, {
|
|
145
|
+
singleton: false;
|
|
146
|
+
optional: false;
|
|
147
|
+
internal: false;
|
|
148
|
+
}>;
|
|
149
|
+
layout: _backstage_frontend_plugin_api.ExtensionInput<_backstage_frontend_plugin_api.ConfigurableExtensionDataRef<(props: HomePageLayoutProps) => react.JSX.Element, "home.layout.component", {}>, {
|
|
82
150
|
singleton: true;
|
|
83
151
|
optional: true;
|
|
84
|
-
internal:
|
|
152
|
+
internal: true;
|
|
85
153
|
}>;
|
|
86
154
|
};
|
|
87
155
|
kind: "page";
|
|
@@ -89,10 +157,13 @@ declare const _default: _backstage_frontend_plugin_api.OverridableFrontendPlugin
|
|
|
89
157
|
params: {
|
|
90
158
|
defaultPath?: [Error: `Use the 'path' param instead`];
|
|
91
159
|
path: string;
|
|
92
|
-
|
|
160
|
+
title?: string;
|
|
161
|
+
icon?: _backstage_frontend_plugin_api.IconElement;
|
|
162
|
+
loader?: () => Promise<react.JSX.Element>;
|
|
93
163
|
routeRef?: _backstage_frontend_plugin_api.RouteRef;
|
|
164
|
+
noHeader?: boolean;
|
|
94
165
|
};
|
|
95
166
|
}>;
|
|
96
167
|
}>;
|
|
97
168
|
|
|
98
|
-
export { _default as default, homeTranslationRef
|
|
169
|
+
export { _default as default, homeTranslationRef };
|
package/dist/alpha.esm.js
CHANGED
|
@@ -1,70 +1,161 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import {
|
|
2
|
+
import { lazy } from 'react';
|
|
3
|
+
import { createRouteRef, PageBlueprint, createExtensionInput, AppRootElementBlueprint, ApiBlueprint, errorApiRef, identityApiRef, storageApiRef, NavItemBlueprint, createFrontendPlugin, ExtensionBoundary } from '@backstage/frontend-plugin-api';
|
|
3
4
|
import 'react-router-dom';
|
|
4
5
|
import './components/CustomHomepage/CustomHomepageGrid.esm.js';
|
|
5
6
|
import { VisitListener } from './components/VisitListener.esm.js';
|
|
6
7
|
import './components/VisitList/Context.esm.js';
|
|
7
8
|
import { VisitsStorageApi } from './api/VisitsStorageApi.esm.js';
|
|
8
|
-
import '
|
|
9
|
+
import { VisitsWebStorageApi } from './api/VisitsWebStorageApi.esm.js';
|
|
9
10
|
import { visitsApiRef } from './api/VisitsApi.esm.js';
|
|
11
|
+
import HomeIcon from '@material-ui/icons/Home';
|
|
12
|
+
import { homePageLayoutComponentDataRef, homePageWidgetDataRef, HomePageLayoutBlueprint, HomePageWidgetBlueprint } from '@backstage/plugin-home-react/alpha';
|
|
10
13
|
export { homeTranslationRef } from './translation.esm.js';
|
|
11
14
|
|
|
12
15
|
const rootRouteRef = createRouteRef();
|
|
13
|
-
const titleExtensionDataRef = createExtensionDataRef().with({
|
|
14
|
-
id: "title"
|
|
15
|
-
});
|
|
16
16
|
const homePage = PageBlueprint.makeWithOverrides({
|
|
17
17
|
inputs: {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
singleton: true,
|
|
25
|
-
optional: true
|
|
26
|
-
}
|
|
27
|
-
)
|
|
18
|
+
widgets: createExtensionInput([homePageWidgetDataRef]),
|
|
19
|
+
layout: createExtensionInput([HomePageLayoutBlueprint.dataRefs.component], {
|
|
20
|
+
singleton: true,
|
|
21
|
+
optional: true,
|
|
22
|
+
internal: true
|
|
23
|
+
})
|
|
28
24
|
},
|
|
29
|
-
factory
|
|
25
|
+
factory(originalFactory, { node, inputs }) {
|
|
30
26
|
return originalFactory({
|
|
31
27
|
path: "/home",
|
|
28
|
+
noHeader: true,
|
|
32
29
|
routeRef: rootRouteRef,
|
|
33
|
-
loader:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
30
|
+
loader: async () => {
|
|
31
|
+
const LazyDefaultLayout = lazy(
|
|
32
|
+
() => import('./alpha/DefaultHomePageLayout.esm.js').then((m) => ({
|
|
33
|
+
default: m.DefaultHomePageLayout
|
|
34
|
+
}))
|
|
35
|
+
);
|
|
36
|
+
const DefaultLayoutComponent = (props) => /* @__PURE__ */ jsx(ExtensionBoundary, { node, children: /* @__PURE__ */ jsx(LazyDefaultLayout, { ...props }) });
|
|
37
|
+
const Layout = inputs.layout?.get(homePageLayoutComponentDataRef) ?? DefaultLayoutComponent;
|
|
38
|
+
const widgets = inputs.widgets.map((widget) => ({
|
|
39
|
+
...widget.get(homePageWidgetDataRef),
|
|
40
|
+
node: widget.node
|
|
41
|
+
}));
|
|
42
|
+
return /* @__PURE__ */ jsx(Layout, { widgets });
|
|
43
|
+
}
|
|
40
44
|
});
|
|
41
45
|
}
|
|
42
46
|
});
|
|
43
47
|
const visitListenerAppRootElement = AppRootElementBlueprint.make({
|
|
44
48
|
name: "visit-listener",
|
|
49
|
+
disabled: true,
|
|
45
50
|
params: {
|
|
46
51
|
element: /* @__PURE__ */ jsx(VisitListener, {})
|
|
47
52
|
}
|
|
48
53
|
});
|
|
49
54
|
const visitsApi = ApiBlueprint.make({
|
|
50
55
|
name: "visits",
|
|
56
|
+
disabled: true,
|
|
51
57
|
params: (defineParams) => defineParams({
|
|
52
58
|
api: visitsApiRef,
|
|
53
59
|
deps: {
|
|
54
60
|
storageApi: storageApiRef,
|
|
55
|
-
identityApi: identityApiRef
|
|
61
|
+
identityApi: identityApiRef,
|
|
62
|
+
errorApi: errorApiRef
|
|
56
63
|
},
|
|
57
|
-
factory: ({ storageApi, identityApi }) =>
|
|
64
|
+
factory: ({ storageApi, identityApi, errorApi }) => {
|
|
65
|
+
if (storageApi) {
|
|
66
|
+
return VisitsStorageApi.create({ storageApi, identityApi });
|
|
67
|
+
}
|
|
68
|
+
return VisitsWebStorageApi.create({ identityApi, errorApi });
|
|
69
|
+
}
|
|
58
70
|
})
|
|
59
71
|
});
|
|
72
|
+
const homeNavItem = NavItemBlueprint.make({
|
|
73
|
+
params: {
|
|
74
|
+
title: "Home",
|
|
75
|
+
routeRef: rootRouteRef,
|
|
76
|
+
icon: HomeIcon
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
const homePageToolkitWidget = HomePageWidgetBlueprint.make({
|
|
80
|
+
name: "toolkit",
|
|
81
|
+
params: {
|
|
82
|
+
name: "HomePageToolkit",
|
|
83
|
+
title: "Toolkit",
|
|
84
|
+
components: () => import('./homePageComponents/Toolkit/index.esm.js').then((m) => ({
|
|
85
|
+
Content: m.Content,
|
|
86
|
+
ContextProvider: m.ContextProvider
|
|
87
|
+
})),
|
|
88
|
+
componentProps: {
|
|
89
|
+
tools: [
|
|
90
|
+
{
|
|
91
|
+
url: "https://backstage.io",
|
|
92
|
+
label: "Backstage Docs",
|
|
93
|
+
icon: /* @__PURE__ */ jsx(HomeIcon, {})
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
const homePageStarredEntitiesWidget = HomePageWidgetBlueprint.make({
|
|
100
|
+
name: "starred-entities",
|
|
101
|
+
params: {
|
|
102
|
+
name: "HomePageStarredEntities",
|
|
103
|
+
title: "Your Starred Entities",
|
|
104
|
+
components: () => import('./homePageComponents/StarredEntities/index.esm.js').then((m) => ({
|
|
105
|
+
Content: m.Content
|
|
106
|
+
}))
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
const homePageRandomJokeWidget = HomePageWidgetBlueprint.make({
|
|
110
|
+
name: "random-joke",
|
|
111
|
+
params: {
|
|
112
|
+
name: "HomePageRandomJoke",
|
|
113
|
+
title: "Random Joke",
|
|
114
|
+
description: "Shows a random programming joke",
|
|
115
|
+
components: () => import('./homePageComponents/RandomJoke/index.esm.js').then((m) => ({
|
|
116
|
+
Content: m.Content,
|
|
117
|
+
Settings: m.Settings,
|
|
118
|
+
Actions: m.Actions,
|
|
119
|
+
ContextProvider: m.ContextProvider
|
|
120
|
+
})),
|
|
121
|
+
layout: {
|
|
122
|
+
height: { minRows: 4 },
|
|
123
|
+
width: { minColumns: 3 }
|
|
124
|
+
},
|
|
125
|
+
settings: {
|
|
126
|
+
schema: {
|
|
127
|
+
title: "Random Joke settings",
|
|
128
|
+
type: "object",
|
|
129
|
+
properties: {
|
|
130
|
+
defaultCategory: {
|
|
131
|
+
title: "Category",
|
|
132
|
+
type: "string",
|
|
133
|
+
enum: ["any", "programming", "dad"],
|
|
134
|
+
default: "any"
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
});
|
|
60
141
|
var alpha = createFrontendPlugin({
|
|
61
142
|
pluginId: "home",
|
|
143
|
+
title: "Home",
|
|
144
|
+
icon: /* @__PURE__ */ jsx(HomeIcon, {}),
|
|
62
145
|
info: { packageJson: () => import('./package.json.esm.js') },
|
|
63
|
-
extensions: [
|
|
146
|
+
extensions: [
|
|
147
|
+
homePage,
|
|
148
|
+
homeNavItem,
|
|
149
|
+
visitsApi,
|
|
150
|
+
visitListenerAppRootElement,
|
|
151
|
+
homePageToolkitWidget,
|
|
152
|
+
homePageStarredEntitiesWidget,
|
|
153
|
+
homePageRandomJokeWidget
|
|
154
|
+
],
|
|
64
155
|
routes: {
|
|
65
156
|
root: rootRouteRef
|
|
66
157
|
}
|
|
67
158
|
});
|
|
68
159
|
|
|
69
|
-
export { alpha as default
|
|
160
|
+
export { alpha as default };
|
|
70
161
|
//# sourceMappingURL=alpha.esm.js.map
|
package/dist/alpha.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alpha.esm.js","sources":["../src/alpha.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 coreExtensionData,\n createExtensionDataRef,\n createExtensionInput,\n PageBlueprint,\n createFrontendPlugin,\n createRouteRef,\n AppRootElementBlueprint,\n identityApiRef,\n storageApiRef,\n ApiBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport { VisitListener } from './components/';\nimport { visitsApiRef, VisitsStorageApi } from './api';\n\nconst rootRouteRef = createRouteRef();\n\n/**\n * @alpha\n */\nexport const titleExtensionDataRef = createExtensionDataRef<string>().with({\n id: 'title',\n});\n\nconst homePage = PageBlueprint.makeWithOverrides({\n inputs: {\n props: createExtensionInput(\n [\n coreExtensionData.reactElement.optional(),\n titleExtensionDataRef.optional(),\n ],\n {\n singleton: true,\n optional: true,\n },\n ),\n },\n factory: (originalFactory, { inputs }) => {\n return originalFactory({\n path: '/home',\n routeRef: rootRouteRef,\n loader: () =>\n import('./components/').then(m => (\n <m.HomepageCompositionRoot\n children={inputs.props?.get(coreExtensionData.reactElement)}\n title={inputs.props?.get(titleExtensionDataRef)}\n />\n )),\n });\n },\n});\n\nconst visitListenerAppRootElement = AppRootElementBlueprint.make({\n name: 'visit-listener',\n params: {\n element: <VisitListener />,\n },\n});\n\nconst visitsApi = ApiBlueprint.make({\n name: 'visits',\n params: defineParams =>\n defineParams({\n api: visitsApiRef,\n deps: {\n storageApi: storageApiRef,\n identityApi: identityApiRef,\n },\n factory: ({ storageApi, identityApi }) =>\n VisitsStorageApi.create({ storageApi, identityApi }),\n }),\n});\n\n/**\n * @alpha\n */\nexport default createFrontendPlugin({\n pluginId: 'home',\n info: { packageJson: () => import('../package.json') },\n extensions: [homePage, visitsApi, visitListenerAppRootElement],\n routes: {\n root: rootRouteRef,\n },\n});\n\nexport { homeTranslationRef } from './translation';\n"],"names":[],"mappings":";;;;;;;;;;;AA+BA,MAAM,eAAe,cAAA,EAAe;AAK7B,MAAM,qBAAA,GAAwB,sBAAA,EAA+B,CAAE,IAAA,CAAK;AAAA,EACzE,EAAA,EAAI;AACN,CAAC;AAED,MAAM,QAAA,GAAW,cAAc,iBAAA,CAAkB;AAAA,EAC/C,MAAA,EAAQ;AAAA,IACN,KAAA,EAAO,oBAAA;AAAA,MACL;AAAA,QACE,iBAAA,CAAkB,aAAa,QAAA,EAAS;AAAA,QACxC,sBAAsB,QAAA;AAAS,OACjC;AAAA,MACA;AAAA,QACE,SAAA,EAAW,IAAA;AAAA,QACX,QAAA,EAAU;AAAA;AACZ;AACF,GACF;AAAA,EACA,OAAA,EAAS,CAAC,eAAA,EAAiB,EAAE,QAAO,KAAM;AACxC,IAAA,OAAO,eAAA,CAAgB;AAAA,MACrB,IAAA,EAAM,OAAA;AAAA,MACN,QAAA,EAAU,YAAA;AAAA,MACV,QAAQ,MACN,OAAO,2BAAe,CAAA,CAAE,KAAK,CAAA,CAAA,qBAC3B,GAAA;AAAA,QAAC,CAAA,CAAE,uBAAA;AAAA,QAAF;AAAA,UACC,QAAA,EAAU,MAAA,CAAO,KAAA,EAAO,GAAA,CAAI,kBAAkB,YAAY,CAAA;AAAA,UAC1D,KAAA,EAAO,MAAA,CAAO,KAAA,EAAO,GAAA,CAAI,qBAAqB;AAAA;AAAA,OAEjD;AAAA,KACJ,CAAA;AAAA,EACH;AACF,CAAC,CAAA;AAED,MAAM,2BAAA,GAA8B,wBAAwB,IAAA,CAAK;AAAA,EAC/D,IAAA,EAAM,gBAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,OAAA,sBAAU,aAAA,EAAA,EAAc;AAAA;AAE5B,CAAC,CAAA;AAED,MAAM,SAAA,GAAY,aAAa,IAAA,CAAK;AAAA,EAClC,IAAA,EAAM,QAAA;AAAA,EACN,MAAA,EAAQ,kBACN,YAAA,CAAa;AAAA,IACX,GAAA,EAAK,YAAA;AAAA,IACL,IAAA,EAAM;AAAA,MACJ,UAAA,EAAY,aAAA;AAAA,MACZ,WAAA,EAAa;AAAA,KACf;AAAA,IACA,OAAA,EAAS,CAAC,EAAE,UAAA,EAAY,WAAA,EAAY,KAClC,gBAAA,CAAiB,MAAA,CAAO,EAAE,UAAA,EAAY,WAAA,EAAa;AAAA,GACtD;AACL,CAAC,CAAA;AAKD,YAAe,oBAAA,CAAqB;AAAA,EAClC,QAAA,EAAU,MAAA;AAAA,EACV,MAAM,EAAE,WAAA,EAAa,MAAM,OAAO,uBAAiB,CAAA,EAAE;AAAA,EACrD,UAAA,EAAY,CAAC,QAAA,EAAU,SAAA,EAAW,2BAA2B,CAAA;AAAA,EAC7D,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM;AAAA;AAEV,CAAC,CAAA;;;;"}
|
|
1
|
+
{"version":3,"file":"alpha.esm.js","sources":["../src/alpha.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\n/**\n * The home plugin for Backstage's new frontend system.\n *\n * @remarks\n * This package provides the new frontend system implementation of the home plugin,\n * which offers customizable home pages with widget support and optional visit tracking.\n *\n * @packageDocumentation\n */\n\nimport { lazy as reactLazy } from 'react';\nimport {\n createExtensionInput,\n PageBlueprint,\n NavItemBlueprint,\n createFrontendPlugin,\n createRouteRef,\n AppRootElementBlueprint,\n identityApiRef,\n storageApiRef,\n errorApiRef,\n ApiBlueprint,\n ExtensionBoundary,\n} from '@backstage/frontend-plugin-api';\nimport { VisitListener } from './components/';\nimport { visitsApiRef, VisitsStorageApi, VisitsWebStorageApi } from './api';\nimport HomeIcon from '@material-ui/icons/Home';\nimport {\n homePageWidgetDataRef,\n homePageLayoutComponentDataRef,\n HomePageLayoutBlueprint,\n HomePageWidgetBlueprint,\n type HomePageLayoutProps,\n} from '@backstage/plugin-home-react/alpha';\n\nconst rootRouteRef = createRouteRef();\n\nconst homePage = PageBlueprint.makeWithOverrides({\n inputs: {\n widgets: createExtensionInput([homePageWidgetDataRef]),\n layout: createExtensionInput([HomePageLayoutBlueprint.dataRefs.component], {\n singleton: true,\n optional: true,\n internal: true,\n }),\n },\n factory(originalFactory, { node, inputs }) {\n return originalFactory({\n path: '/home',\n noHeader: true,\n routeRef: rootRouteRef,\n loader: async () => {\n const LazyDefaultLayout = reactLazy(() =>\n import('./alpha/DefaultHomePageLayout').then(m => ({\n default: m.DefaultHomePageLayout,\n })),\n );\n\n const DefaultLayoutComponent = (props: HomePageLayoutProps) => (\n <ExtensionBoundary node={node}>\n <LazyDefaultLayout {...props} />\n </ExtensionBoundary>\n );\n\n const Layout =\n inputs.layout?.get(homePageLayoutComponentDataRef) ??\n DefaultLayoutComponent;\n\n const widgets = inputs.widgets.map(widget => ({\n ...widget.get(homePageWidgetDataRef),\n node: widget.node,\n }));\n\n return <Layout widgets={widgets} />;\n },\n });\n },\n});\n\nconst visitListenerAppRootElement = AppRootElementBlueprint.make({\n name: 'visit-listener',\n disabled: true,\n params: {\n element: <VisitListener />,\n },\n});\n\nconst visitsApi = ApiBlueprint.make({\n name: 'visits',\n disabled: true,\n params: defineParams =>\n defineParams({\n api: visitsApiRef,\n deps: {\n storageApi: storageApiRef,\n identityApi: identityApiRef,\n errorApi: errorApiRef,\n },\n factory: ({ storageApi, identityApi, errorApi }) => {\n // Smart fallback: use custom storage API if available, otherwise localStorage\n if (storageApi) {\n return VisitsStorageApi.create({ storageApi, identityApi });\n }\n return VisitsWebStorageApi.create({ identityApi, errorApi });\n },\n }),\n});\n\nconst homeNavItem = NavItemBlueprint.make({\n params: {\n title: 'Home',\n routeRef: rootRouteRef,\n icon: HomeIcon,\n },\n});\n\nconst homePageToolkitWidget = HomePageWidgetBlueprint.make({\n name: 'toolkit',\n params: {\n name: 'HomePageToolkit',\n title: 'Toolkit',\n components: () =>\n import('./homePageComponents/Toolkit').then(m => ({\n Content: m.Content,\n ContextProvider: m.ContextProvider,\n })),\n componentProps: {\n tools: [\n {\n url: 'https://backstage.io',\n label: 'Backstage Docs',\n icon: <HomeIcon />,\n },\n ],\n },\n },\n});\n\nconst homePageStarredEntitiesWidget = HomePageWidgetBlueprint.make({\n name: 'starred-entities',\n params: {\n name: 'HomePageStarredEntities',\n title: 'Your Starred Entities',\n components: () =>\n import('./homePageComponents/StarredEntities').then(m => ({\n Content: m.Content,\n })),\n },\n});\n\nconst homePageRandomJokeWidget = HomePageWidgetBlueprint.make({\n name: 'random-joke',\n params: {\n name: 'HomePageRandomJoke',\n title: 'Random Joke',\n description: 'Shows a random programming joke',\n components: () =>\n import('./homePageComponents/RandomJoke').then(m => ({\n Content: m.Content,\n Settings: m.Settings,\n Actions: m.Actions,\n ContextProvider: m.ContextProvider,\n })),\n layout: {\n height: { minRows: 4 },\n width: { minColumns: 3 },\n },\n settings: {\n schema: {\n title: 'Random Joke settings',\n type: 'object',\n properties: {\n defaultCategory: {\n title: 'Category',\n type: 'string',\n enum: ['any', 'programming', 'dad'],\n default: 'any',\n },\n },\n },\n },\n },\n});\n\n/**\n * Home plugin for the new frontend system.\n *\n * Provides core homepage functionality with optional visit tracking extensions.\n * Visit tracking extensions are disabled by default and can be enabled via app-config.yaml.\n *\n * @alpha\n */\nexport default createFrontendPlugin({\n pluginId: 'home',\n title: 'Home',\n icon: <HomeIcon />,\n info: { packageJson: () => import('../package.json') },\n extensions: [\n homePage,\n homeNavItem,\n visitsApi,\n visitListenerAppRootElement,\n homePageToolkitWidget,\n homePageStarredEntitiesWidget,\n homePageRandomJokeWidget,\n ],\n routes: {\n root: rootRouteRef,\n },\n});\n\nexport { homeTranslationRef } from './translation';\n"],"names":["reactLazy"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VisitsApi.esm.js","sources":["../../src/api/VisitsApi.ts"],"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 { createApiRef } from '@backstage/core-plugin-api';\nimport { VisitInput } from './VisitsStorageApi';\n\n/**\n * @public\n * The operators that can be used in filter.\n */\nexport type Operators = '<' | '<=' | '==' | '!=' | '>' | '>=' | 'contains';\n\n/**\n * @public\n * Type guard for operators.\n */\nexport const isOperator = (s: string): s is Operators => {\n return ['<', '<=', '==', '!=', '>', '>=', 'contains'].includes(s);\n};\n\n/**\n * @public\n * Model for a visit entity.\n */\nexport type Visit = {\n /**\n * The auto-generated visit identification.\n */\n id: string;\n /**\n * The visited entity, usually an entity id.\n */\n name: string;\n /**\n * The visited url pathname, usually the entity route.\n */\n pathname: string;\n /**\n * An individual view count.\n */\n hits: number;\n /**\n * Last date and time of visit. Format: unix epoch in ms.\n */\n timestamp: number;\n /**\n * Optional entity reference. See stringifyEntityRef from catalog-model.\n */\n entityRef?: string;\n};\n\n/**\n * @public\n * This data structure represents the parameters associated with search queries for visits.\n */\nexport type VisitsApiQueryParams = {\n /**\n * Limits the number of results returned. The default is 8.\n */\n limit?: number;\n /**\n * Allows ordering visits on entity properties.\n * @example\n * Sort ascending by the timestamp field.\n * ```\n * { orderBy: [{ field: 'timestamp', direction: 'asc' }] }\n * ```\n */\n orderBy?: Array<{\n field: keyof Visit;\n direction: 'asc' | 'desc';\n }>;\n /**\n * Allows filtering visits on entity properties.\n * @example\n * Most popular docs on the past 7 days\n * ```\n * {\n * orderBy: [{ field: 'hits', direction: 'desc' }],\n * filterBy: [\n * { field: 'timestamp', operator: '>=', value: <date> },\n * { field: 'entityRef', operator: 'contains', value: 'docs' }\n * ]\n * }\n * ```\n */\n filterBy?: Array<{\n field: keyof Visit;\n operator: Operators;\n value: string | number;\n }>;\n};\n\n/**\n * @public\n * This data structure represents the parameters associated with saving visits.\n */\nexport type VisitsApiSaveParams = {\n visit: Omit<Visit, 'id' | 'hits' | 'timestamp'>;\n};\n\n/**\n * @public\n * Visits API public contract.\n */\nexport interface VisitsApi {\n /**\n * Persist a new visit.\n * @param pageVisit - a new visit data\n */\n save(saveParams: VisitsApiSaveParams): Promise<Visit>;\n /**\n * Get user visits.\n * @param queryParams - optional search query params.\n */\n list(queryParams?: VisitsApiQueryParams): Promise<Visit[]>;\n /**\n * Transform the pathname before it is considered for any other processing.\n * @param pathname - the original pathname\n */\n transformPathname?(pathname: string): string;\n /**\n * Determine whether a visit should be saved.\n * @param visit - page visit data\n */\n canSave?(visit: VisitInput): boolean | Promise<boolean>;\n /**\n * Add additional data to the visit before saving.\n * @param visit - page visit data\n */\n enrichVisit?(\n visit: VisitInput,\n ): Promise<Record<string, any>> | Record<string, any>;\n}\n\n
|
|
1
|
+
{"version":3,"file":"VisitsApi.esm.js","sources":["../../src/api/VisitsApi.ts"],"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 { createApiRef } from '@backstage/core-plugin-api';\nimport { VisitInput } from './VisitsStorageApi';\n\n/**\n * @public\n * The operators that can be used in filter.\n */\nexport type Operators = '<' | '<=' | '==' | '!=' | '>' | '>=' | 'contains';\n\n/**\n * @public\n * Type guard for operators.\n */\nexport const isOperator = (s: string): s is Operators => {\n return ['<', '<=', '==', '!=', '>', '>=', 'contains'].includes(s);\n};\n\n/**\n * @public\n * Model for a visit entity.\n */\nexport type Visit = {\n /**\n * The auto-generated visit identification.\n */\n id: string;\n /**\n * The visited entity, usually an entity id.\n */\n name: string;\n /**\n * The visited url pathname, usually the entity route.\n */\n pathname: string;\n /**\n * An individual view count.\n */\n hits: number;\n /**\n * Last date and time of visit. Format: unix epoch in ms.\n */\n timestamp: number;\n /**\n * Optional entity reference. See stringifyEntityRef from catalog-model.\n */\n entityRef?: string;\n};\n\n/**\n * @public\n * This data structure represents the parameters associated with search queries for visits.\n */\nexport type VisitsApiQueryParams = {\n /**\n * Limits the number of results returned. The default is 8.\n */\n limit?: number;\n /**\n * Allows ordering visits on entity properties.\n * @example\n * Sort ascending by the timestamp field.\n * ```\n * { orderBy: [{ field: 'timestamp', direction: 'asc' }] }\n * ```\n */\n orderBy?: Array<{\n field: keyof Visit;\n direction: 'asc' | 'desc';\n }>;\n /**\n * Allows filtering visits on entity properties.\n * @example\n * Most popular docs on the past 7 days\n * ```\n * {\n * orderBy: [{ field: 'hits', direction: 'desc' }],\n * filterBy: [\n * { field: 'timestamp', operator: '>=', value: <date> },\n * { field: 'entityRef', operator: 'contains', value: 'docs' }\n * ]\n * }\n * ```\n */\n filterBy?: Array<{\n field: keyof Visit;\n operator: Operators;\n value: string | number;\n }>;\n};\n\n/**\n * @public\n * This data structure represents the parameters associated with saving visits.\n */\nexport type VisitsApiSaveParams = {\n visit: Omit<Visit, 'id' | 'hits' | 'timestamp'>;\n};\n\n/**\n * @public\n * Visits API public contract.\n */\nexport interface VisitsApi {\n /**\n * Persist a new visit.\n * @param pageVisit - a new visit data\n */\n save(saveParams: VisitsApiSaveParams): Promise<Visit>;\n /**\n * Get user visits.\n * @param queryParams - optional search query params.\n */\n list(queryParams?: VisitsApiQueryParams): Promise<Visit[]>;\n /**\n * Transform the pathname before it is considered for any other processing.\n * @param pathname - the original pathname\n */\n transformPathname?(pathname: string): string;\n /**\n * Determine whether a visit should be saved.\n * @param visit - page visit data\n */\n canSave?(visit: VisitInput): boolean | Promise<boolean>;\n /**\n * Add additional data to the visit before saving.\n * @param visit - page visit data\n */\n enrichVisit?(\n visit: VisitInput,\n ): Promise<Record<string, any>> | Record<string, any>;\n}\n\n/**\n * API reference for the visits tracking service.\n * Provides functionality to track and retrieve user page visit history.\n *\n * @public\n */\nexport const visitsApiRef = createApiRef<VisitsApi>({\n id: 'homepage.visits',\n});\n"],"names":[],"mappings":";;AA6BO,MAAM,UAAA,GAAa,CAAC,CAAA,KAA8B;AACvD,EAAA,OAAO,CAAC,GAAA,EAAK,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,KAAK,IAAA,EAAM,UAAU,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA;AAClE;AA2HO,MAAM,eAAe,YAAA,CAAwB;AAAA,EAClD,EAAA,EAAI;AACN,CAAC;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -156,7 +156,12 @@ interface VisitsApi {
|
|
|
156
156
|
*/
|
|
157
157
|
enrichVisit?(visit: VisitInput): Promise<Record<string, any>> | Record<string, any>;
|
|
158
158
|
}
|
|
159
|
-
/**
|
|
159
|
+
/**
|
|
160
|
+
* API reference for the visits tracking service.
|
|
161
|
+
* Provides functionality to track and retrieve user page visit history.
|
|
162
|
+
*
|
|
163
|
+
* @public
|
|
164
|
+
*/
|
|
160
165
|
declare const visitsApiRef: _backstage_frontend_plugin_api.ApiRef<VisitsApi>;
|
|
161
166
|
|
|
162
167
|
/**
|
package/dist/package.json.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var name = "@backstage/plugin-home";
|
|
2
|
-
var version = "0.9.2
|
|
2
|
+
var version = "0.9.2";
|
|
3
3
|
var description = "A Backstage plugin that helps you build a home page";
|
|
4
4
|
var backstage = {
|
|
5
5
|
role: "frontend-plugin",
|
|
@@ -59,6 +59,7 @@ var dependencies = {
|
|
|
59
59
|
"@backstage/catalog-model": "workspace:^",
|
|
60
60
|
"@backstage/config": "workspace:^",
|
|
61
61
|
"@backstage/core-app-api": "workspace:^",
|
|
62
|
+
"@backstage/core-compat-api": "workspace:^",
|
|
62
63
|
"@backstage/core-components": "workspace:^",
|
|
63
64
|
"@backstage/core-plugin-api": "workspace:^",
|
|
64
65
|
"@backstage/frontend-plugin-api": "workspace:^",
|
|
@@ -82,6 +83,8 @@ var dependencies = {
|
|
|
82
83
|
var devDependencies = {
|
|
83
84
|
"@backstage/cli": "workspace:^",
|
|
84
85
|
"@backstage/dev-utils": "workspace:^",
|
|
86
|
+
"@backstage/frontend-defaults": "workspace:^",
|
|
87
|
+
"@backstage/plugin-catalog": "workspace:^",
|
|
85
88
|
"@backstage/test-utils": "workspace:^",
|
|
86
89
|
"@testing-library/dom": "^10.0.0",
|
|
87
90
|
"@testing-library/jest-dom": "^6.0.0",
|
|
@@ -91,13 +94,13 @@ var devDependencies = {
|
|
|
91
94
|
"@types/react-grid-layout": "^1.3.2",
|
|
92
95
|
react: "^18.0.2",
|
|
93
96
|
"react-dom": "^18.0.2",
|
|
94
|
-
"react-router-dom": "^6.
|
|
97
|
+
"react-router-dom": "^6.30.2"
|
|
95
98
|
};
|
|
96
99
|
var peerDependencies = {
|
|
97
100
|
"@types/react": "^17.0.0 || ^18.0.0",
|
|
98
101
|
react: "^17.0.0 || ^18.0.0",
|
|
99
102
|
"react-dom": "^17.0.0 || ^18.0.0",
|
|
100
|
-
"react-router-dom": "^6.
|
|
103
|
+
"react-router-dom": "^6.30.2"
|
|
101
104
|
};
|
|
102
105
|
var peerDependenciesMeta = {
|
|
103
106
|
"@types/react": {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package.json.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"package.json.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translation.esm.js","sources":["../src/translation.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { createTranslationRef } from '@backstage/frontend-plugin-api';\n\n/**\n * @alpha\n */\nexport const homeTranslationRef = createTranslationRef({\n id: 'home',\n messages: {\n addWidgetDialog: {\n title: 'Add new widget to dashboard',\n },\n customHomepageButtons: {\n edit: 'Edit',\n restoreDefaults: 'Restore defaults',\n clearAll: 'Clear all',\n addWidget: 'Add widget',\n save: 'Save',\n cancel: 'Cancel',\n },\n customHomepage: {\n noWidgets: \"No widgets added. Start by clicking the 'Add widget' button.\",\n },\n widgetSettingsOverlay: {\n editSettingsTooptip: 'Edit settings',\n deleteWidgetTooltip: 'Delete widget',\n submitButtonTitle: 'Submit',\n cancelButtonTitle: 'Cancel',\n },\n starredEntityListItem: {\n removeFavoriteEntityTitle: 'Remove entity from favorites',\n },\n visitList: {\n empty: {\n title: 'There are no visits to show yet.',\n description:\n 'Once you start using Backstage, your visits will appear here as a quick link to carry on where you left off.',\n },\n few: {\n title: 'The more pages you visit, the more pages will appear here.',\n },\n },\n quickStart: {\n title: 'Onboarding',\n description: 'Get started with Backstage',\n learnMoreLinkTitle: 'Learn more',\n },\n starredEntities: {\n noStarredEntitiesMessage:\n 'Click the star beside an entity name to add it to this list!',\n },\n visitedByType: {\n action: {\n viewMore: 'View more',\n viewLess: 'View less',\n },\n },\n featuredDocsCard: {\n learnMoreTitle: 'LEARN MORE',\n empty: {\n title: 'No documents to show',\n description:\n 'Create your own document. Check out our Getting Started Information',\n learnMoreLinkTitle: 'DOCS',\n },\n },\n },\n});\n"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"translation.esm.js","sources":["../src/translation.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { createTranslationRef } from '@backstage/frontend-plugin-api';\n\n/**\n * Translation reference for the home plugin.\n * Contains localized text strings for home page components and widgets.\n *\n * @alpha\n */\nexport const homeTranslationRef = createTranslationRef({\n id: 'home',\n messages: {\n addWidgetDialog: {\n title: 'Add new widget to dashboard',\n },\n customHomepageButtons: {\n edit: 'Edit',\n restoreDefaults: 'Restore defaults',\n clearAll: 'Clear all',\n addWidget: 'Add widget',\n save: 'Save',\n cancel: 'Cancel',\n },\n customHomepage: {\n noWidgets: \"No widgets added. Start by clicking the 'Add widget' button.\",\n },\n widgetSettingsOverlay: {\n editSettingsTooptip: 'Edit settings',\n deleteWidgetTooltip: 'Delete widget',\n submitButtonTitle: 'Submit',\n cancelButtonTitle: 'Cancel',\n },\n starredEntityListItem: {\n removeFavoriteEntityTitle: 'Remove entity from favorites',\n },\n visitList: {\n empty: {\n title: 'There are no visits to show yet.',\n description:\n 'Once you start using Backstage, your visits will appear here as a quick link to carry on where you left off.',\n },\n few: {\n title: 'The more pages you visit, the more pages will appear here.',\n },\n },\n quickStart: {\n title: 'Onboarding',\n description: 'Get started with Backstage',\n learnMoreLinkTitle: 'Learn more',\n },\n starredEntities: {\n noStarredEntitiesMessage:\n 'Click the star beside an entity name to add it to this list!',\n },\n visitedByType: {\n action: {\n viewMore: 'View more',\n viewLess: 'View less',\n },\n },\n featuredDocsCard: {\n learnMoreTitle: 'LEARN MORE',\n empty: {\n title: 'No documents to show',\n description:\n 'Create your own document. Check out our Getting Started Information',\n learnMoreLinkTitle: 'DOCS',\n },\n },\n },\n});\n"],"names":[],"mappings":";;AAuBO,MAAM,qBAAqB,oBAAA,CAAqB;AAAA,EACrD,EAAA,EAAI,MAAA;AAAA,EACJ,QAAA,EAAU;AAAA,IACR,eAAA,EAAiB;AAAA,MACf,KAAA,EAAO;AAAA,KACT;AAAA,IACA,qBAAA,EAAuB;AAAA,MACrB,IAAA,EAAM,MAAA;AAAA,MACN,eAAA,EAAiB,kBAAA;AAAA,MACjB,QAAA,EAAU,WAAA;AAAA,MACV,SAAA,EAAW,YAAA;AAAA,MACX,IAAA,EAAM,MAAA;AAAA,MACN,MAAA,EAAQ;AAAA,KACV;AAAA,IACA,cAAA,EAAgB;AAAA,MACd,SAAA,EAAW;AAAA,KACb;AAAA,IACA,qBAAA,EAAuB;AAAA,MACrB,mBAAA,EAAqB,eAAA;AAAA,MACrB,mBAAA,EAAqB,eAAA;AAAA,MACrB,iBAAA,EAAmB,QAAA;AAAA,MACnB,iBAAA,EAAmB;AAAA,KACrB;AAAA,IACA,qBAAA,EAAuB;AAAA,MACrB,yBAAA,EAA2B;AAAA,KAC7B;AAAA,IACA,SAAA,EAAW;AAAA,MACT,KAAA,EAAO;AAAA,QACL,KAAA,EAAO,kCAAA;AAAA,QACP,WAAA,EACE;AAAA,OACJ;AAAA,MACA,GAAA,EAAK;AAAA,QACH,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,UAAA,EAAY;AAAA,MACV,KAAA,EAAO,YAAA;AAAA,MACP,WAAA,EAAa,4BAAA;AAAA,MACb,kBAAA,EAAoB;AAAA,KACtB;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,wBAAA,EACE;AAAA,KACJ;AAAA,IACA,aAAA,EAAe;AAAA,MACb,MAAA,EAAQ;AAAA,QACN,QAAA,EAAU,WAAA;AAAA,QACV,QAAA,EAAU;AAAA;AACZ,KACF;AAAA,IACA,gBAAA,EAAkB;AAAA,MAChB,cAAA,EAAgB,YAAA;AAAA,MAChB,KAAA,EAAO;AAAA,QACL,KAAA,EAAO,sBAAA;AAAA,QACP,WAAA,EACE,qEAAA;AAAA,QACF,kBAAA,EAAoB;AAAA;AACtB;AACF;AAEJ,CAAC;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-home",
|
|
3
|
-
"version": "0.9.2
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "A Backstage plugin that helps you build a home page",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "frontend-plugin",
|
|
@@ -68,16 +68,17 @@
|
|
|
68
68
|
"test": "backstage-cli package test"
|
|
69
69
|
},
|
|
70
70
|
"dependencies": {
|
|
71
|
-
"@backstage/catalog-client": "1.
|
|
72
|
-
"@backstage/catalog-model": "1.7.6",
|
|
73
|
-
"@backstage/config": "1.3.6",
|
|
74
|
-
"@backstage/core-app-api": "1.19.5
|
|
75
|
-
"@backstage/core-
|
|
76
|
-
"@backstage/core-
|
|
77
|
-
"@backstage/
|
|
78
|
-
"@backstage/plugin-
|
|
79
|
-
"@backstage/plugin-
|
|
80
|
-
"@backstage/
|
|
71
|
+
"@backstage/catalog-client": "^1.13.0",
|
|
72
|
+
"@backstage/catalog-model": "^1.7.6",
|
|
73
|
+
"@backstage/config": "^1.3.6",
|
|
74
|
+
"@backstage/core-app-api": "^1.19.5",
|
|
75
|
+
"@backstage/core-compat-api": "^0.5.8",
|
|
76
|
+
"@backstage/core-components": "^0.18.7",
|
|
77
|
+
"@backstage/core-plugin-api": "^1.12.3",
|
|
78
|
+
"@backstage/frontend-plugin-api": "^0.14.0",
|
|
79
|
+
"@backstage/plugin-catalog-react": "^2.0.0",
|
|
80
|
+
"@backstage/plugin-home-react": "^0.1.35",
|
|
81
|
+
"@backstage/theme": "^0.7.2",
|
|
81
82
|
"@material-ui/core": "^4.12.2",
|
|
82
83
|
"@material-ui/icons": "^4.9.1",
|
|
83
84
|
"@material-ui/lab": "4.0.0-alpha.61",
|
|
@@ -93,9 +94,11 @@
|
|
|
93
94
|
"zod": "^3.25.76"
|
|
94
95
|
},
|
|
95
96
|
"devDependencies": {
|
|
96
|
-
"@backstage/cli": "0.35.4
|
|
97
|
-
"@backstage/dev-utils": "1.1.20
|
|
98
|
-
"@backstage/
|
|
97
|
+
"@backstage/cli": "^0.35.4",
|
|
98
|
+
"@backstage/dev-utils": "^1.1.20",
|
|
99
|
+
"@backstage/frontend-defaults": "^0.4.0",
|
|
100
|
+
"@backstage/plugin-catalog": "^1.33.0",
|
|
101
|
+
"@backstage/test-utils": "^1.7.15",
|
|
99
102
|
"@testing-library/dom": "^10.0.0",
|
|
100
103
|
"@testing-library/jest-dom": "^6.0.0",
|
|
101
104
|
"@testing-library/react": "^16.0.0",
|
|
@@ -104,13 +107,13 @@
|
|
|
104
107
|
"@types/react-grid-layout": "^1.3.2",
|
|
105
108
|
"react": "^18.0.2",
|
|
106
109
|
"react-dom": "^18.0.2",
|
|
107
|
-
"react-router-dom": "^6.
|
|
110
|
+
"react-router-dom": "^6.30.2"
|
|
108
111
|
},
|
|
109
112
|
"peerDependencies": {
|
|
110
113
|
"@types/react": "^17.0.0 || ^18.0.0",
|
|
111
114
|
"react": "^17.0.0 || ^18.0.0",
|
|
112
115
|
"react-dom": "^17.0.0 || ^18.0.0",
|
|
113
|
-
"react-router-dom": "^6.
|
|
116
|
+
"react-router-dom": "^6.30.2"
|
|
114
117
|
},
|
|
115
118
|
"peerDependenciesMeta": {
|
|
116
119
|
"@types/react": {
|