@backstage/plugin-home 0.9.9-next.1 → 0.9.9
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 +25 -0
- package/README.md +3 -642
- package/dist/alpha/DefaultHomePageLayout.esm.js +16 -3
- package/dist/alpha/DefaultHomePageLayout.esm.js.map +1 -1
- package/dist/alpha.d.ts +79 -2
- package/dist/alpha.esm.js +112 -21
- package/dist/alpha.esm.js.map +1 -1
- package/dist/components/CustomHomepage/CustomHomepageGrid.esm.js +32 -11
- package/dist/components/CustomHomepage/CustomHomepageGrid.esm.js.map +1 -1
- package/dist/homePageComponents/HeaderWorldClock/HeaderWorldClock.esm.js +1 -37
- package/dist/homePageComponents/HeaderWorldClock/HeaderWorldClock.esm.js.map +1 -1
- package/dist/homePageComponents/Toolkit/Content.esm.js +4 -1
- package/dist/homePageComponents/Toolkit/Content.esm.js.map +1 -1
- package/dist/homePageComponents/VisitedByType/Content.esm.js +20 -6
- package/dist/homePageComponents/VisitedByType/Content.esm.js.map +1 -1
- package/dist/homePageComponents/VisitedByType/RecentlyVisited.esm.js +3 -3
- package/dist/homePageComponents/VisitedByType/TopVisited.esm.js +3 -3
- package/dist/homePageComponents/WorldClock/WorldClock.esm.js +55 -0
- package/dist/homePageComponents/WorldClock/WorldClock.esm.js.map +1 -0
- package/dist/homePageComponents/WorldClock/clocks.esm.js +40 -0
- package/dist/homePageComponents/WorldClock/clocks.esm.js.map +1 -0
- package/dist/homePageComponents/WorldClock/index.esm.js +6 -0
- package/dist/homePageComponents/WorldClock/index.esm.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/package.json.esm.js +1 -1
- package/dist/translation.esm.js +4 -0
- package/dist/translation.esm.js.map +1 -1
- package/package.json +17 -17
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { Fragment } from 'react';
|
|
2
|
+
import { useMemo, Fragment } from 'react';
|
|
3
3
|
import { Content } from '@backstage/core-components';
|
|
4
4
|
import 'react-router-dom';
|
|
5
5
|
import { CustomHomepageGrid } from '../components/CustomHomepage/CustomHomepageGrid.esm.js';
|
|
@@ -10,8 +10,21 @@ import '@backstage/catalog-model';
|
|
|
10
10
|
import '../components/VisitList/Context.esm.js';
|
|
11
11
|
|
|
12
12
|
function DefaultHomePageLayout(props) {
|
|
13
|
-
const { widgets } = props;
|
|
14
|
-
|
|
13
|
+
const { widgets, defaultConfig } = props;
|
|
14
|
+
const gridConfig = useMemo(
|
|
15
|
+
() => defaultConfig?.map((item) => ({
|
|
16
|
+
component: item.component,
|
|
17
|
+
x: item.column,
|
|
18
|
+
y: item.row,
|
|
19
|
+
width: item.width,
|
|
20
|
+
height: item.height,
|
|
21
|
+
movable: item.movable,
|
|
22
|
+
deletable: item.deletable,
|
|
23
|
+
resizable: item.resizable
|
|
24
|
+
})),
|
|
25
|
+
[defaultConfig]
|
|
26
|
+
);
|
|
27
|
+
return /* @__PURE__ */ jsx(Content, { children: /* @__PURE__ */ jsx(CustomHomepageGrid, { config: gridConfig, children: widgets.map((widget, index) => /* @__PURE__ */ jsx(Fragment, { children: widget.component }, widget.name ?? index)) }) });
|
|
15
28
|
}
|
|
16
29
|
|
|
17
30
|
export { DefaultHomePageLayout };
|
|
@@ -1 +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,
|
|
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, useMemo } 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, defaultConfig } = props;\n const gridConfig = useMemo(\n () =>\n defaultConfig?.map(item => ({\n component: item.component,\n x: item.column,\n y: item.row,\n width: item.width,\n height: item.height,\n movable: item.movable,\n deletable: item.deletable,\n resizable: item.resizable,\n })),\n [defaultConfig],\n );\n return (\n <Content>\n <CustomHomepageGrid config={gridConfig}>\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,OAAA,EAAS,aAAA,EAAc,GAAI,KAAA;AACnC,EAAA,MAAM,UAAA,GAAa,OAAA;AAAA,IACjB,MACE,aAAA,EAAe,GAAA,CAAI,CAAA,IAAA,MAAS;AAAA,MAC1B,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,GAAG,IAAA,CAAK,MAAA;AAAA,MACR,GAAG,IAAA,CAAK,GAAA;AAAA,MACR,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,WAAW,IAAA,CAAK;AAAA,KAClB,CAAE,CAAA;AAAA,IACJ,CAAC,aAAa;AAAA,GAChB;AACA,EAAA,uBACE,GAAA,CAAC,WACC,QAAA,kBAAA,GAAA,CAAC,kBAAA,EAAA,EAAmB,QAAQ,UAAA,EACzB,QAAA,EAAA,OAAA,CAAQ,IAAI,CAAC,MAAA,EAAQ,0BACpB,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
|
@@ -34,6 +34,15 @@ declare const _default: _backstage_frontend_plugin_api.OverridableFrontendPlugin
|
|
|
34
34
|
element: JSX.Element;
|
|
35
35
|
};
|
|
36
36
|
}>;
|
|
37
|
+
"home-page-widget:home/most-visited": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
38
|
+
kind: "home-page-widget";
|
|
39
|
+
name: "most-visited";
|
|
40
|
+
config: {};
|
|
41
|
+
configInput: {};
|
|
42
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_plugin_home_react_alpha.HomePageWidgetData, "home.widget.data", {}>;
|
|
43
|
+
inputs: {};
|
|
44
|
+
params: _backstage_plugin_home_react_alpha.HomePageWidgetBlueprintParams;
|
|
45
|
+
}>;
|
|
37
46
|
"home-page-widget:home/random-joke": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
38
47
|
kind: "home-page-widget";
|
|
39
48
|
name: "random-joke";
|
|
@@ -43,6 +52,15 @@ declare const _default: _backstage_frontend_plugin_api.OverridableFrontendPlugin
|
|
|
43
52
|
inputs: {};
|
|
44
53
|
params: _backstage_plugin_home_react_alpha.HomePageWidgetBlueprintParams;
|
|
45
54
|
}>;
|
|
55
|
+
"home-page-widget:home/recently-visited": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
56
|
+
kind: "home-page-widget";
|
|
57
|
+
name: "recently-visited";
|
|
58
|
+
config: {};
|
|
59
|
+
configInput: {};
|
|
60
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_plugin_home_react_alpha.HomePageWidgetData, "home.widget.data", {}>;
|
|
61
|
+
inputs: {};
|
|
62
|
+
params: _backstage_plugin_home_react_alpha.HomePageWidgetBlueprintParams;
|
|
63
|
+
}>;
|
|
46
64
|
"home-page-widget:home/starred-entities": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
47
65
|
kind: "home-page-widget";
|
|
48
66
|
name: "starred-entities";
|
|
@@ -53,20 +71,77 @@ declare const _default: _backstage_frontend_plugin_api.OverridableFrontendPlugin
|
|
|
53
71
|
params: _backstage_plugin_home_react_alpha.HomePageWidgetBlueprintParams;
|
|
54
72
|
}>;
|
|
55
73
|
"home-page-widget:home/toolkit": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
74
|
+
config: {
|
|
75
|
+
tools: {
|
|
76
|
+
url: string;
|
|
77
|
+
label: string;
|
|
78
|
+
icon?: string | undefined;
|
|
79
|
+
}[];
|
|
80
|
+
};
|
|
81
|
+
configInput: {
|
|
82
|
+
tools?: {
|
|
83
|
+
url: string;
|
|
84
|
+
label: string;
|
|
85
|
+
icon?: string | undefined;
|
|
86
|
+
}[] | undefined;
|
|
87
|
+
};
|
|
88
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_plugin_home_react_alpha.HomePageWidgetData, "home.widget.data", {}>;
|
|
89
|
+
inputs: {};
|
|
56
90
|
kind: "home-page-widget";
|
|
57
91
|
name: "toolkit";
|
|
58
|
-
|
|
59
|
-
|
|
92
|
+
params: _backstage_plugin_home_react_alpha.HomePageWidgetBlueprintParams;
|
|
93
|
+
}>;
|
|
94
|
+
"home-page-widget:home/world-clock": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
95
|
+
config: {
|
|
96
|
+
clockConfigs: {
|
|
97
|
+
label: string;
|
|
98
|
+
timeZone: string;
|
|
99
|
+
}[] | undefined;
|
|
100
|
+
customTimeFormat: {
|
|
101
|
+
hour12?: boolean | undefined;
|
|
102
|
+
} | undefined;
|
|
103
|
+
};
|
|
104
|
+
configInput: {
|
|
105
|
+
clockConfigs?: {
|
|
106
|
+
label: string;
|
|
107
|
+
timeZone: string;
|
|
108
|
+
}[] | undefined;
|
|
109
|
+
customTimeFormat?: {
|
|
110
|
+
hour12?: boolean | undefined;
|
|
111
|
+
} | undefined;
|
|
112
|
+
};
|
|
60
113
|
output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_plugin_home_react_alpha.HomePageWidgetData, "home.widget.data", {}>;
|
|
61
114
|
inputs: {};
|
|
115
|
+
kind: "home-page-widget";
|
|
116
|
+
name: "world-clock";
|
|
62
117
|
params: _backstage_plugin_home_react_alpha.HomePageWidgetBlueprintParams;
|
|
63
118
|
}>;
|
|
64
119
|
"page:home": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
65
120
|
config: {
|
|
121
|
+
defaultConfig: {
|
|
122
|
+
component: string;
|
|
123
|
+
column: number;
|
|
124
|
+
row: number;
|
|
125
|
+
width: number;
|
|
126
|
+
height: number;
|
|
127
|
+
movable?: boolean | undefined;
|
|
128
|
+
deletable?: boolean | undefined;
|
|
129
|
+
resizable?: boolean | undefined;
|
|
130
|
+
}[] | undefined;
|
|
66
131
|
path: string | undefined;
|
|
67
132
|
title: string | undefined;
|
|
68
133
|
};
|
|
69
134
|
configInput: {
|
|
135
|
+
defaultConfig?: {
|
|
136
|
+
component: string;
|
|
137
|
+
column: number;
|
|
138
|
+
row: number;
|
|
139
|
+
width: number;
|
|
140
|
+
height: number;
|
|
141
|
+
movable?: boolean | undefined;
|
|
142
|
+
deletable?: boolean | undefined;
|
|
143
|
+
resizable?: boolean | undefined;
|
|
144
|
+
}[] | undefined;
|
|
70
145
|
path?: string | undefined;
|
|
71
146
|
title?: string | undefined;
|
|
72
147
|
};
|
|
@@ -134,6 +209,8 @@ declare const homeTranslationRef: _backstage_frontend_plugin_api.TranslationRef<
|
|
|
134
209
|
readonly "widgetSettingsOverlay.deleteWidgetTooltip": "Delete widget";
|
|
135
210
|
readonly "widgetSettingsOverlay.submitButtonTitle": "Submit";
|
|
136
211
|
readonly "starredEntityListItem.removeFavoriteEntityTitle": "Remove entity from favorites";
|
|
212
|
+
readonly "visitList.disabled.title": "Visit tracking is not enabled.";
|
|
213
|
+
readonly "visitList.disabled.description": "Enable visit tracking in your app-config.yaml to see your most visited and recently visited pages here.";
|
|
137
214
|
readonly "visitList.empty.title": "There are no visits to show yet.";
|
|
138
215
|
readonly "visitList.empty.description": "Once you start using Backstage, your visits will appear here as a quick link to carry on where you left off.";
|
|
139
216
|
readonly "visitList.few.title": "The more pages you visit, the more pages will appear here.";
|
package/dist/alpha.esm.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { lazy } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { z } from 'zod/v4';
|
|
4
|
+
import { createRouteRef, PageBlueprint, createExtensionInput, AppRootElementBlueprint, ApiBlueprint, errorApiRef, identityApiRef, storageApiRef, iconsApiRef, createFrontendPlugin, ExtensionBoundary } from '@backstage/frontend-plugin-api';
|
|
5
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
4
6
|
import 'react-router-dom';
|
|
5
7
|
import './components/CustomHomepage/CustomHomepageGrid.esm.js';
|
|
6
8
|
import { VisitListener } from './components/VisitListener.esm.js';
|
|
@@ -9,10 +11,21 @@ import { VisitsStorageApi } from './api/VisitsStorageApi.esm.js';
|
|
|
9
11
|
import { VisitsWebStorageApi } from './api/VisitsWebStorageApi.esm.js';
|
|
10
12
|
import { visitsApiRef } from './api/VisitsApi.esm.js';
|
|
11
13
|
import HomeIcon from '@material-ui/icons/Home';
|
|
14
|
+
import LinkIcon from '@material-ui/icons/Link';
|
|
12
15
|
import { homePageLayoutComponentDataRef, homePageWidgetDataRef, HomePageLayoutBlueprint, HomePageWidgetBlueprint } from '@backstage/plugin-home-react/alpha';
|
|
13
16
|
import { homeTranslationRef as homeTranslationRef$1 } from './translation.esm.js';
|
|
14
17
|
|
|
15
18
|
const rootRouteRef = createRouteRef();
|
|
19
|
+
const defaultConfigItemSchema = z.object({
|
|
20
|
+
component: z.string(),
|
|
21
|
+
column: z.number(),
|
|
22
|
+
row: z.number(),
|
|
23
|
+
width: z.number(),
|
|
24
|
+
height: z.number(),
|
|
25
|
+
movable: z.boolean().optional(),
|
|
26
|
+
deletable: z.boolean().optional(),
|
|
27
|
+
resizable: z.boolean().optional()
|
|
28
|
+
});
|
|
16
29
|
const homePage = PageBlueprint.makeWithOverrides({
|
|
17
30
|
inputs: {
|
|
18
31
|
widgets: createExtensionInput([homePageWidgetDataRef]),
|
|
@@ -22,7 +35,10 @@ const homePage = PageBlueprint.makeWithOverrides({
|
|
|
22
35
|
internal: true
|
|
23
36
|
})
|
|
24
37
|
},
|
|
25
|
-
|
|
38
|
+
configSchema: {
|
|
39
|
+
defaultConfig: z.array(defaultConfigItemSchema).optional()
|
|
40
|
+
},
|
|
41
|
+
factory(originalFactory, { node, inputs, config }) {
|
|
26
42
|
return originalFactory({
|
|
27
43
|
path: "/home",
|
|
28
44
|
noHeader: true,
|
|
@@ -41,7 +57,7 @@ const homePage = PageBlueprint.makeWithOverrides({
|
|
|
41
57
|
...widget.get(homePageWidgetDataRef),
|
|
42
58
|
node: widget.node
|
|
43
59
|
}));
|
|
44
|
-
return /* @__PURE__ */ jsx(Layout, { widgets });
|
|
60
|
+
return /* @__PURE__ */ jsx(Layout, { widgets, defaultConfig: config.defaultConfig });
|
|
45
61
|
}
|
|
46
62
|
});
|
|
47
63
|
}
|
|
@@ -71,24 +87,35 @@ const visitsApi = ApiBlueprint.make({
|
|
|
71
87
|
}
|
|
72
88
|
})
|
|
73
89
|
});
|
|
74
|
-
const homePageToolkitWidget = HomePageWidgetBlueprint.
|
|
90
|
+
const homePageToolkitWidget = HomePageWidgetBlueprint.makeWithOverrides({
|
|
75
91
|
name: "toolkit",
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
+
configSchema: {
|
|
93
|
+
tools: z.array(
|
|
94
|
+
z.object({
|
|
95
|
+
url: z.string(),
|
|
96
|
+
label: z.string(),
|
|
97
|
+
icon: z.string().optional()
|
|
98
|
+
})
|
|
99
|
+
).default([{ url: "https://backstage.io", label: "Backstage Docs" }])
|
|
100
|
+
},
|
|
101
|
+
*factory(originalFactory, { config }) {
|
|
102
|
+
yield* originalFactory({
|
|
103
|
+
name: "HomePageToolkit",
|
|
104
|
+
title: "Toolkit",
|
|
105
|
+
description: "A collection of useful links and tools",
|
|
106
|
+
components: () => import('./homePageComponents/Toolkit/index.esm.js').then((m) => ({
|
|
107
|
+
Content: (props) => {
|
|
108
|
+
const iconsApi = useApi(iconsApiRef);
|
|
109
|
+
const tools = config.tools.map((tool) => ({
|
|
110
|
+
url: tool.url,
|
|
111
|
+
label: tool.label,
|
|
112
|
+
icon: (tool.icon && iconsApi.icon(tool.icon)) ?? /* @__PURE__ */ jsx(LinkIcon, {})
|
|
113
|
+
}));
|
|
114
|
+
return /* @__PURE__ */ jsx(m.Content, { ...props, tools });
|
|
115
|
+
},
|
|
116
|
+
ContextProvider: m.ContextProvider
|
|
117
|
+
}))
|
|
118
|
+
});
|
|
92
119
|
}
|
|
93
120
|
});
|
|
94
121
|
const homePageStarredEntitiesWidget = HomePageWidgetBlueprint.make({
|
|
@@ -96,6 +123,7 @@ const homePageStarredEntitiesWidget = HomePageWidgetBlueprint.make({
|
|
|
96
123
|
params: {
|
|
97
124
|
name: "HomePageStarredEntities",
|
|
98
125
|
title: "Your Starred Entities",
|
|
126
|
+
description: "Shows entities you have starred in the catalog",
|
|
99
127
|
components: () => import('./homePageComponents/StarredEntities/index.esm.js').then((m) => ({
|
|
100
128
|
Content: m.Content
|
|
101
129
|
}))
|
|
@@ -133,6 +161,66 @@ const homePageRandomJokeWidget = HomePageWidgetBlueprint.make({
|
|
|
133
161
|
}
|
|
134
162
|
}
|
|
135
163
|
});
|
|
164
|
+
const homePageMostVisitedWidget = HomePageWidgetBlueprint.make({
|
|
165
|
+
name: "most-visited",
|
|
166
|
+
params: {
|
|
167
|
+
name: "HomePageMostVisited",
|
|
168
|
+
title: "Most Visited",
|
|
169
|
+
description: "Shows your most frequently visited pages",
|
|
170
|
+
components: () => import('./homePageComponents/VisitedByType/TopVisited.esm.js').then((m) => ({
|
|
171
|
+
Content: m.Content,
|
|
172
|
+
Actions: m.Actions,
|
|
173
|
+
ContextProvider: m.ContextProvider
|
|
174
|
+
}))
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
const homePageRecentlyVisitedWidget = HomePageWidgetBlueprint.make({
|
|
178
|
+
name: "recently-visited",
|
|
179
|
+
params: {
|
|
180
|
+
name: "HomePageRecentlyVisited",
|
|
181
|
+
title: "Recently Visited",
|
|
182
|
+
description: "Shows pages you have recently visited",
|
|
183
|
+
components: () => import('./homePageComponents/VisitedByType/RecentlyVisited.esm.js').then((m) => ({
|
|
184
|
+
Content: m.Content,
|
|
185
|
+
Actions: m.Actions,
|
|
186
|
+
ContextProvider: m.ContextProvider
|
|
187
|
+
}))
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
const homePageWorldClockWidget = HomePageWidgetBlueprint.makeWithOverrides({
|
|
191
|
+
name: "world-clock",
|
|
192
|
+
configSchema: {
|
|
193
|
+
clockConfigs: z.array(
|
|
194
|
+
z.object({
|
|
195
|
+
label: z.string(),
|
|
196
|
+
timeZone: z.string()
|
|
197
|
+
})
|
|
198
|
+
).optional(),
|
|
199
|
+
customTimeFormat: z.object({
|
|
200
|
+
hour12: z.boolean().optional()
|
|
201
|
+
}).optional()
|
|
202
|
+
},
|
|
203
|
+
*factory(originalFactory, { config }) {
|
|
204
|
+
yield* originalFactory({
|
|
205
|
+
name: "HomePageWorldClock",
|
|
206
|
+
title: "World Clocks",
|
|
207
|
+
description: "Displays clocks for configured time zones",
|
|
208
|
+
components: () => import('./homePageComponents/WorldClock/index.esm.js').then((m) => ({
|
|
209
|
+
Content: () => /* @__PURE__ */ jsx(
|
|
210
|
+
m.WorldClock,
|
|
211
|
+
{
|
|
212
|
+
clockConfigs: config.clockConfigs,
|
|
213
|
+
customTimeFormat: config.customTimeFormat ? {
|
|
214
|
+
hour: "2-digit",
|
|
215
|
+
minute: "2-digit",
|
|
216
|
+
...config.customTimeFormat
|
|
217
|
+
} : void 0
|
|
218
|
+
}
|
|
219
|
+
)
|
|
220
|
+
}))
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
});
|
|
136
224
|
var alpha = createFrontendPlugin({
|
|
137
225
|
pluginId: "home",
|
|
138
226
|
title: "Home",
|
|
@@ -144,7 +232,10 @@ var alpha = createFrontendPlugin({
|
|
|
144
232
|
visitListenerAppRootElement,
|
|
145
233
|
homePageToolkitWidget,
|
|
146
234
|
homePageStarredEntitiesWidget,
|
|
147
|
-
homePageRandomJokeWidget
|
|
235
|
+
homePageRandomJokeWidget,
|
|
236
|
+
homePageMostVisitedWidget,
|
|
237
|
+
homePageRecentlyVisitedWidget,
|
|
238
|
+
homePageWorldClockWidget
|
|
148
239
|
],
|
|
149
240
|
routes: {
|
|
150
241
|
root: rootRouteRef
|
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\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 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 title: 'Home',\n icon: <HomeIcon fontSize=\"inherit\" />,\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 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 visitsApi,\n visitListenerAppRootElement,\n homePageToolkitWidget,\n homePageStarredEntitiesWidget,\n homePageRandomJokeWidget,\n ],\n routes: {\n root: rootRouteRef,\n },\n});\n\nimport { homeTranslationRef as _homeTranslationRef } from './translation';\n\n/**\n * @alpha\n * @deprecated Import from `@backstage/plugin-home` instead.\n */\nexport const homeTranslationRef = _homeTranslationRef;\n"],"names":["reactLazy","_homeTranslationRef"],"mappings":"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"}
|
|
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 { z } from 'zod/v4';\nimport {\n createExtensionInput,\n PageBlueprint,\n createFrontendPlugin,\n createRouteRef,\n AppRootElementBlueprint,\n identityApiRef,\n storageApiRef,\n errorApiRef,\n ApiBlueprint,\n ExtensionBoundary,\n iconsApiRef,\n} from '@backstage/frontend-plugin-api';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { VisitListener } from './components/';\nimport { visitsApiRef, VisitsStorageApi, VisitsWebStorageApi } from './api';\nimport HomeIcon from '@material-ui/icons/Home';\nimport LinkIcon from '@material-ui/icons/Link';\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 defaultConfigItemSchema = z.object({\n component: z.string(),\n column: z.number(),\n row: z.number(),\n width: z.number(),\n height: z.number(),\n movable: z.boolean().optional(),\n deletable: z.boolean().optional(),\n resizable: z.boolean().optional(),\n});\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 configSchema: {\n defaultConfig: z.array(defaultConfigItemSchema).optional(),\n },\n factory(originalFactory, { node, inputs, config }) {\n return originalFactory({\n path: '/home',\n noHeader: true,\n routeRef: rootRouteRef,\n title: 'Home',\n icon: <HomeIcon fontSize=\"inherit\" />,\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 (\n <Layout widgets={widgets} defaultConfig={config.defaultConfig} />\n );\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 homePageToolkitWidget = HomePageWidgetBlueprint.makeWithOverrides({\n name: 'toolkit',\n configSchema: {\n tools: z\n .array(\n z.object({\n url: z.string(),\n label: z.string(),\n icon: z.string().optional(),\n }),\n )\n .default([{ url: 'https://backstage.io', label: 'Backstage Docs' }]),\n },\n *factory(originalFactory, { config }) {\n yield* originalFactory({\n name: 'HomePageToolkit',\n title: 'Toolkit',\n description: 'A collection of useful links and tools',\n components: () =>\n import('./homePageComponents/Toolkit').then(m => ({\n Content: (props: Record<string, unknown>) => {\n const iconsApi = useApi(iconsApiRef);\n const tools = config.tools.map(tool => ({\n url: tool.url,\n label: tool.label,\n icon: (tool.icon && iconsApi.icon(tool.icon)) ?? <LinkIcon />,\n }));\n return <m.Content {...props} tools={tools} />;\n },\n ContextProvider: m.ContextProvider,\n })),\n });\n },\n});\n\nconst homePageStarredEntitiesWidget = HomePageWidgetBlueprint.make({\n name: 'starred-entities',\n params: {\n name: 'HomePageStarredEntities',\n title: 'Your Starred Entities',\n description: 'Shows entities you have starred in the catalog',\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\nconst homePageMostVisitedWidget = HomePageWidgetBlueprint.make({\n name: 'most-visited',\n params: {\n name: 'HomePageMostVisited',\n title: 'Most Visited',\n description: 'Shows your most frequently visited pages',\n components: () =>\n import('./homePageComponents/VisitedByType/TopVisited').then(m => ({\n Content: m.Content,\n Actions: m.Actions,\n ContextProvider: m.ContextProvider,\n })),\n },\n});\n\nconst homePageRecentlyVisitedWidget = HomePageWidgetBlueprint.make({\n name: 'recently-visited',\n params: {\n name: 'HomePageRecentlyVisited',\n title: 'Recently Visited',\n description: 'Shows pages you have recently visited',\n components: () =>\n import('./homePageComponents/VisitedByType/RecentlyVisited').then(m => ({\n Content: m.Content,\n Actions: m.Actions,\n ContextProvider: m.ContextProvider,\n })),\n },\n});\n\nconst homePageWorldClockWidget = HomePageWidgetBlueprint.makeWithOverrides({\n name: 'world-clock',\n configSchema: {\n clockConfigs: z\n .array(\n z.object({\n label: z.string(),\n timeZone: z.string(),\n }),\n )\n .optional(),\n customTimeFormat: z\n .object({\n hour12: z.boolean().optional(),\n })\n .optional(),\n },\n *factory(originalFactory, { config }) {\n yield* originalFactory({\n name: 'HomePageWorldClock',\n title: 'World Clocks',\n description: 'Displays clocks for configured time zones',\n components: () =>\n import('./homePageComponents/WorldClock').then(m => ({\n Content: () => (\n <m.WorldClock\n clockConfigs={config.clockConfigs}\n customTimeFormat={\n config.customTimeFormat\n ? {\n hour: '2-digit',\n minute: '2-digit',\n ...config.customTimeFormat,\n }\n : undefined\n }\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 visitsApi,\n visitListenerAppRootElement,\n homePageToolkitWidget,\n homePageStarredEntitiesWidget,\n homePageRandomJokeWidget,\n homePageMostVisitedWidget,\n homePageRecentlyVisitedWidget,\n homePageWorldClockWidget,\n ],\n routes: {\n root: rootRouteRef,\n },\n});\n\nimport { homeTranslationRef as _homeTranslationRef } from './translation';\n\n/**\n * @alpha\n * @deprecated Import from `@backstage/plugin-home` instead.\n */\nexport const homeTranslationRef = _homeTranslationRef;\n"],"names":["reactLazy","_homeTranslationRef"],"mappings":"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"}
|
|
@@ -46,6 +46,15 @@ const useStyles = makeStyles(
|
|
|
46
46
|
"&.edit > :active": {
|
|
47
47
|
cursor: "move"
|
|
48
48
|
}
|
|
49
|
+
},
|
|
50
|
+
layoutLabel: {
|
|
51
|
+
position: "absolute",
|
|
52
|
+
bottom: 4,
|
|
53
|
+
left: 8,
|
|
54
|
+
fontSize: "0.7rem",
|
|
55
|
+
color: theme.palette.text.disabled,
|
|
56
|
+
pointerEvents: "none",
|
|
57
|
+
zIndex: 1
|
|
49
58
|
}
|
|
50
59
|
})
|
|
51
60
|
);
|
|
@@ -332,17 +341,29 @@ const CustomHomepageGrid = (props) => {
|
|
|
332
341
|
className: `${styles.widgetWrapper} ${editMode && "edit"} ${w.movable === false && "disabled"}`,
|
|
333
342
|
children: [
|
|
334
343
|
/* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(widget.component.type, { ...widgetProps }) }),
|
|
335
|
-
editMode && /* @__PURE__ */
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
344
|
+
editMode && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
345
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: styles.layoutLabel, children: [
|
|
346
|
+
"column: ",
|
|
347
|
+
l.x,
|
|
348
|
+
", row: ",
|
|
349
|
+
l.y,
|
|
350
|
+
", width: ",
|
|
351
|
+
l.w,
|
|
352
|
+
", height: ",
|
|
353
|
+
l.h
|
|
354
|
+
] }),
|
|
355
|
+
/* @__PURE__ */ jsx(
|
|
356
|
+
WidgetSettingsOverlay,
|
|
357
|
+
{
|
|
358
|
+
id: l.i,
|
|
359
|
+
widget,
|
|
360
|
+
handleRemove,
|
|
361
|
+
handleSettingsSave,
|
|
362
|
+
settings: w.settings,
|
|
363
|
+
deletable: w.deletable
|
|
364
|
+
}
|
|
365
|
+
)
|
|
366
|
+
] })
|
|
346
367
|
]
|
|
347
368
|
},
|
|
348
369
|
l.i
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomHomepageGrid.esm.js","sources":["../../../src/components/CustomHomepage/CustomHomepageGrid.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 isValidElement,\n useState,\n useCallback,\n useMemo,\n useEffect,\n} from 'react';\nimport { Layout, Layouts, Responsive, WidthProvider } from 'react-grid-layout';\nimport {\n ElementCollection,\n getComponentData,\n storageApiRef,\n useApi,\n useElementFilter,\n} from '@backstage/core-plugin-api';\nimport 'react-grid-layout/css/styles.css';\nimport 'react-resizable/css/styles.css';\nimport Dialog from '@material-ui/core/Dialog';\nimport {\n createStyles,\n makeStyles,\n Theme,\n useTheme,\n} from '@material-ui/core/styles';\nimport { compact } from 'lodash';\nimport useObservable from 'react-use/esm/useObservable';\nimport {\n ContentHeader,\n ErrorBoundary,\n Progress,\n} from '@backstage/core-components';\nimport Typography from '@material-ui/core/Typography';\nimport { WidgetSettingsOverlay } from './WidgetSettingsOverlay';\nimport { AddWidgetDialog } from './AddWidgetDialog';\nimport { CustomHomepageButtons } from './CustomHomepageButtons';\nimport {\n CustomHomepageGridProps,\n CustomHomepageGridStateV1,\n CustomHomepageGridStateV1Schema,\n GridWidget,\n LayoutConfiguration,\n LayoutConfigurationSchema,\n Widget,\n WidgetSchema,\n} from './types';\nimport { CardConfig } from '@backstage/plugin-home-react';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport { homeTranslationRef } from '../../translation';\n\n// eslint-disable-next-line new-cap\nconst ResponsiveGrid = WidthProvider(Responsive);\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n responsiveGrid: {\n '& .react-grid-item > .react-resizable-handle:after': {\n position: 'absolute',\n content: '\"\"',\n borderStyle: 'solid',\n borderWidth: '0 0 20px 20px',\n borderColor: `transparent transparent ${theme.palette.primary.light} transparent`,\n },\n },\n contentHeaderBtn: {\n marginLeft: theme.spacing(2),\n },\n widgetWrapper: {\n '& > div[class*=\"MuiCard-root\"]': {\n width: '100%',\n height: '100%',\n },\n '& div[class*=\"MuiCardContent-root\"]': {\n overflow: 'auto',\n },\n '& + .react-grid-placeholder': {\n backgroundColor: theme.palette.primary.light,\n },\n '&.edit > :active': {\n cursor: 'move',\n },\n },\n }),\n);\n\nfunction useHomeStorage(\n defaultWidgets: GridWidget[],\n): [GridWidget[], (value: GridWidget[]) => void, boolean] {\n const key = 'home';\n const storageApi = useApi(storageApiRef).forBucket('home.customHomepage');\n // TODO: Support multiple home pages\n const setWidgets = useCallback(\n (value: GridWidget[]) => {\n const grid: CustomHomepageGridStateV1 = {\n version: 1,\n pages: {\n default: value,\n },\n };\n storageApi.set(key, JSON.stringify(grid));\n },\n [key, storageApi],\n );\n const homeSnapshot = useObservable(\n storageApi.observe$<string>(key),\n storageApi.snapshot(key),\n );\n\n const isStorageLoading = homeSnapshot.presence === 'unknown' || !homeSnapshot;\n\n const widgets: GridWidget[] = useMemo(() => {\n if (homeSnapshot.presence === 'absent') {\n return defaultWidgets;\n }\n try {\n const grid: CustomHomepageGridStateV1 = JSON.parse(homeSnapshot.value!);\n return CustomHomepageGridStateV1Schema.parse(grid).pages.default;\n } catch (e) {\n return defaultWidgets;\n }\n }, [homeSnapshot, defaultWidgets]);\n\n return [widgets, setWidgets, isStorageLoading];\n}\n\nconst convertConfigToDefaultWidgets = (\n config: LayoutConfiguration[],\n availableWidgets: Widget[],\n): GridWidget[] => {\n const ret = config.map((conf, i) => {\n const c = LayoutConfigurationSchema.parse(conf);\n const name = isValidElement(c.component)\n ? getComponentData(c.component, 'core.extensionName')\n : (c.component as unknown as string);\n if (!name) {\n return null;\n }\n const widget = availableWidgets.find(w => w.name === name);\n if (!widget) {\n return null;\n }\n const widgetId = `${widget.name}__${i}${Math.random()\n .toString(36)\n .slice(2)}`;\n return {\n id: widgetId,\n layout: {\n i: widgetId,\n x: c.x,\n y: c.y,\n w: Math.min(widget.maxWidth ?? Number.MAX_VALUE, c.width),\n h: Math.min(widget.maxHeight ?? Number.MAX_VALUE, c.height),\n minW: widget.minWidth,\n maxW: widget.maxWidth,\n minH: widget.minHeight,\n maxH: widget.maxHeight,\n isDraggable: false,\n isResizable: false,\n },\n settings: {},\n movable: conf.movable,\n deletable: conf.deletable,\n resizable: conf.resizable,\n };\n });\n return compact(ret);\n};\n\nconst availableWidgetsFilter = (elements: ElementCollection) => {\n return elements\n .selectByComponentData({\n key: 'core.extensionName',\n })\n .getElements<Widget>()\n .flatMap(elem => {\n const config = getComponentData<CardConfig>(elem, 'home.widget.config');\n return [\n WidgetSchema.parse({\n component: elem,\n name: getComponentData<string>(elem, 'core.extensionName'),\n title: getComponentData<string>(elem, 'title'),\n description: getComponentData<string>(elem, 'description'),\n settingsSchema: config?.settings?.schema,\n uiSchema: config?.settings?.uiSchema,\n width: config?.layout?.width?.defaultColumns,\n minWidth: config?.layout?.width?.minColumns,\n maxWidth: config?.layout?.width?.maxColumns,\n height: config?.layout?.height?.defaultRows,\n minHeight: config?.layout?.height?.minRows,\n maxHeight: config?.layout?.height?.maxRows,\n }),\n ];\n });\n};\n\n/**\n * A component that allows customizing components in home grid layout.\n *\n * @public\n */\nexport const CustomHomepageGrid = (props: CustomHomepageGridProps) => {\n const styles = useStyles();\n const theme = useTheme();\n const availableWidgets = useElementFilter(\n props.children,\n availableWidgetsFilter,\n [props],\n );\n const defaultLayout = useMemo(() => {\n return props.config\n ? convertConfigToDefaultWidgets(props.config, availableWidgets)\n : [];\n }, [props.config, availableWidgets]);\n const [storedWidgets, storeWidgets, isStorageLoading] =\n useHomeStorage(defaultLayout);\n const [widgets, setWidgets] = useState(storedWidgets);\n\n const preventDuplicateWidgets = props.preventDuplicateWidgets ?? false;\n\n const [addWidgetDialogOpen, setAddWidgetDialogOpen] = useState(false);\n const editModeOn = widgets.find(w => w.layout.isResizable) !== undefined;\n const [editMode, setEditMode] = useState(editModeOn);\n\n useEffect(() => {\n setWidgets(storedWidgets);\n }, [storedWidgets]);\n\n const getWidgetByName = (name: string) => {\n return availableWidgets.find(widget => widget.name === name);\n };\n\n const getWidgetNameFromKey = (key: string) => {\n return key.split('__')[0];\n };\n const { t } = useTranslationRef(homeTranslationRef);\n\n const getAvailableWidgets = () => {\n if (!preventDuplicateWidgets) {\n return availableWidgets;\n }\n const usedWidgetNames = new Set(\n widgets.map(w => getWidgetNameFromKey(w.id)),\n );\n return availableWidgets.filter(widget => !usedWidgetNames.has(widget.name));\n };\n\n const handleAdd = (widget: Widget) => {\n const widgetId = `${widget.name}__${widgets.length + 1}${Math.random()\n .toString(36)\n .slice(2)}`;\n\n setWidgets([\n ...widgets,\n {\n id: widgetId,\n layout: {\n i: widgetId,\n x: 0,\n y: Math.max(...widgets.map(w => w.layout.y + w.layout.h)) + 1,\n w: Math.min(widget.maxWidth ?? Number.MAX_VALUE, widget.width ?? 12),\n h: Math.min(widget.maxHeight ?? Number.MAX_VALUE, widget.height ?? 4),\n minW: widget.minWidth,\n maxW: widget.maxWidth,\n minH: widget.minHeight,\n maxH: widget.maxHeight,\n isResizable: editMode,\n isDraggable: editMode,\n },\n settings: {},\n movable: widget.movable,\n deletable: widget.deletable,\n resizable: widget.resizable,\n },\n ]);\n setAddWidgetDialogOpen(false);\n };\n\n const handleRemove = (widgetId: string) => {\n setWidgets(widgets.filter(w => w.id !== widgetId));\n };\n\n const handleSettingsSave = (\n widgetId: string,\n widgetSettings: Record<string, any>,\n ) => {\n const idx = widgets.findIndex(w => w.id === widgetId);\n if (idx >= 0) {\n const widget = widgets[idx];\n widget.settings = widgetSettings;\n widgets[idx] = widget;\n setWidgets(widgets);\n }\n };\n\n const clearLayout = () => {\n setWidgets(widgets.filter(w => w.deletable === false));\n };\n\n const changeEditMode = (mode: boolean) => {\n setEditMode(mode);\n\n const newWidgets = widgets.map(w => {\n const resizable = w.resizable === false ? false : mode;\n const movable = w.movable === false ? false : mode;\n return {\n ...w,\n layout: { ...w.layout, isDraggable: movable, isResizable: resizable },\n };\n });\n\n if (mode) {\n setWidgets(newWidgets);\n } else {\n storeWidgets(newWidgets);\n }\n };\n\n const handleLayoutChange = (newLayout: Layout[], _: Layouts) => {\n if (editMode) {\n const newWidgets = newLayout.map(l => {\n const widget = widgets.find(w => w.id === l.i);\n return {\n ...widget,\n layout: l,\n } as GridWidget;\n });\n setWidgets(newWidgets);\n }\n };\n\n const handleRestoreDefaultConfig = () => {\n setWidgets(\n defaultLayout.map(w => {\n const resizable = w.resizable === false ? false : editMode;\n const movable = w.movable === false ? false : editMode;\n return {\n ...w,\n layout: {\n ...w.layout,\n isDraggable: movable,\n isResizable: resizable,\n },\n };\n }),\n );\n };\n\n const handleCancel = () => {\n setWidgets(storedWidgets);\n setEditMode(false);\n };\n\n if (isStorageLoading) {\n return <Progress />;\n }\n\n return (\n <>\n <ContentHeader title={props.title}>\n <CustomHomepageButtons\n editMode={editMode}\n numWidgets={widgets.length}\n clearLayout={clearLayout}\n setAddWidgetDialogOpen={setAddWidgetDialogOpen}\n changeEditMode={changeEditMode}\n defaultConfigAvailable={props.config !== undefined}\n restoreDefault={handleRestoreDefaultConfig}\n cancel={handleCancel}\n />\n </ContentHeader>\n <Dialog\n open={addWidgetDialogOpen}\n onClose={() => setAddWidgetDialogOpen(false)}\n >\n {/* Only mount when open so the list does not update (e.g. remove the added widget) before the modal closes */}\n {addWidgetDialogOpen && (\n <AddWidgetDialog\n widgets={getAvailableWidgets()}\n handleAdd={handleAdd}\n />\n )}\n </Dialog>\n {!editMode && widgets.length === 0 && (\n <Typography variant=\"h5\" align=\"center\">\n {t('customHomepage.noWidgets')}\n </Typography>\n )}\n <ResponsiveGrid\n className={styles.responsiveGrid}\n measureBeforeMount\n compactType={props.compactType}\n style={props.style}\n allowOverlap={props.allowOverlap}\n preventCollision={props.preventCollision ?? true}\n draggableCancel=\".overlayGridItem,.widgetSettingsDialog,.disabled\"\n containerPadding={props.containerPadding}\n margin={props.containerMargin}\n breakpoints={\n props.breakpoints ? props.breakpoints : theme.breakpoints.values\n }\n cols={\n props.cols\n ? props.cols\n : { xl: 12, lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }\n }\n rowHeight={props.rowHeight ?? 60}\n onLayoutChange={handleLayoutChange}\n layouts={{ xl: widgets.map(w => w.layout) }}\n >\n {widgets.map((w: GridWidget) => {\n const l = w.layout;\n const widgetName = getWidgetNameFromKey(l.i);\n const widget = getWidgetByName(widgetName);\n if (!widget || !widget.component) {\n return null;\n }\n\n const widgetProps = {\n ...widget.component.props,\n ...(w.settings ?? {}),\n };\n\n return (\n <div\n key={l.i}\n className={`${styles.widgetWrapper} ${editMode && 'edit'} ${\n w.movable === false && 'disabled'\n }`}\n >\n <ErrorBoundary>\n <widget.component.type {...widgetProps} />\n </ErrorBoundary>\n {editMode && (\n <WidgetSettingsOverlay\n id={l.i}\n widget={widget}\n handleRemove={handleRemove}\n handleSettingsSave={handleSettingsSave}\n settings={w.settings}\n deletable={w.deletable}\n />\n )}\n </div>\n );\n })}\n </ResponsiveGrid>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CustomHomepageGrid.esm.js","sources":["../../../src/components/CustomHomepage/CustomHomepageGrid.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 isValidElement,\n useState,\n useCallback,\n useMemo,\n useEffect,\n} from 'react';\nimport { Layout, Layouts, Responsive, WidthProvider } from 'react-grid-layout';\nimport {\n ElementCollection,\n getComponentData,\n storageApiRef,\n useApi,\n useElementFilter,\n} from '@backstage/core-plugin-api';\nimport 'react-grid-layout/css/styles.css';\nimport 'react-resizable/css/styles.css';\nimport Dialog from '@material-ui/core/Dialog';\nimport {\n createStyles,\n makeStyles,\n Theme,\n useTheme,\n} from '@material-ui/core/styles';\nimport { compact } from 'lodash';\nimport useObservable from 'react-use/esm/useObservable';\nimport {\n ContentHeader,\n ErrorBoundary,\n Progress,\n} from '@backstage/core-components';\nimport Typography from '@material-ui/core/Typography';\nimport { WidgetSettingsOverlay } from './WidgetSettingsOverlay';\nimport { AddWidgetDialog } from './AddWidgetDialog';\nimport { CustomHomepageButtons } from './CustomHomepageButtons';\nimport {\n CustomHomepageGridProps,\n CustomHomepageGridStateV1,\n CustomHomepageGridStateV1Schema,\n GridWidget,\n LayoutConfiguration,\n LayoutConfigurationSchema,\n Widget,\n WidgetSchema,\n} from './types';\nimport { CardConfig } from '@backstage/plugin-home-react';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport { homeTranslationRef } from '../../translation';\n\n// eslint-disable-next-line new-cap\nconst ResponsiveGrid = WidthProvider(Responsive);\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n responsiveGrid: {\n '& .react-grid-item > .react-resizable-handle:after': {\n position: 'absolute',\n content: '\"\"',\n borderStyle: 'solid',\n borderWidth: '0 0 20px 20px',\n borderColor: `transparent transparent ${theme.palette.primary.light} transparent`,\n },\n },\n contentHeaderBtn: {\n marginLeft: theme.spacing(2),\n },\n widgetWrapper: {\n '& > div[class*=\"MuiCard-root\"]': {\n width: '100%',\n height: '100%',\n },\n '& div[class*=\"MuiCardContent-root\"]': {\n overflow: 'auto',\n },\n '& + .react-grid-placeholder': {\n backgroundColor: theme.palette.primary.light,\n },\n '&.edit > :active': {\n cursor: 'move',\n },\n },\n layoutLabel: {\n position: 'absolute',\n bottom: 4,\n left: 8,\n fontSize: '0.7rem',\n color: theme.palette.text.disabled,\n pointerEvents: 'none',\n zIndex: 1,\n },\n }),\n);\n\nfunction useHomeStorage(\n defaultWidgets: GridWidget[],\n): [GridWidget[], (value: GridWidget[]) => void, boolean] {\n const key = 'home';\n const storageApi = useApi(storageApiRef).forBucket('home.customHomepage');\n // TODO: Support multiple home pages\n const setWidgets = useCallback(\n (value: GridWidget[]) => {\n const grid: CustomHomepageGridStateV1 = {\n version: 1,\n pages: {\n default: value,\n },\n };\n storageApi.set(key, JSON.stringify(grid));\n },\n [key, storageApi],\n );\n const homeSnapshot = useObservable(\n storageApi.observe$<string>(key),\n storageApi.snapshot(key),\n );\n\n const isStorageLoading = homeSnapshot.presence === 'unknown' || !homeSnapshot;\n\n const widgets: GridWidget[] = useMemo(() => {\n if (homeSnapshot.presence === 'absent') {\n return defaultWidgets;\n }\n try {\n const grid: CustomHomepageGridStateV1 = JSON.parse(homeSnapshot.value!);\n return CustomHomepageGridStateV1Schema.parse(grid).pages.default;\n } catch (e) {\n return defaultWidgets;\n }\n }, [homeSnapshot, defaultWidgets]);\n\n return [widgets, setWidgets, isStorageLoading];\n}\n\nconst convertConfigToDefaultWidgets = (\n config: LayoutConfiguration[],\n availableWidgets: Widget[],\n): GridWidget[] => {\n const ret = config.map((conf, i) => {\n const c = LayoutConfigurationSchema.parse(conf);\n const name = isValidElement(c.component)\n ? getComponentData(c.component, 'core.extensionName')\n : (c.component as unknown as string);\n if (!name) {\n return null;\n }\n const widget = availableWidgets.find(w => w.name === name);\n if (!widget) {\n return null;\n }\n const widgetId = `${widget.name}__${i}${Math.random()\n .toString(36)\n .slice(2)}`;\n return {\n id: widgetId,\n layout: {\n i: widgetId,\n x: c.x,\n y: c.y,\n w: Math.min(widget.maxWidth ?? Number.MAX_VALUE, c.width),\n h: Math.min(widget.maxHeight ?? Number.MAX_VALUE, c.height),\n minW: widget.minWidth,\n maxW: widget.maxWidth,\n minH: widget.minHeight,\n maxH: widget.maxHeight,\n isDraggable: false,\n isResizable: false,\n },\n settings: {},\n movable: conf.movable,\n deletable: conf.deletable,\n resizable: conf.resizable,\n };\n });\n return compact(ret);\n};\n\nconst availableWidgetsFilter = (elements: ElementCollection) => {\n return elements\n .selectByComponentData({\n key: 'core.extensionName',\n })\n .getElements<Widget>()\n .flatMap(elem => {\n const config = getComponentData<CardConfig>(elem, 'home.widget.config');\n return [\n WidgetSchema.parse({\n component: elem,\n name: getComponentData<string>(elem, 'core.extensionName'),\n title: getComponentData<string>(elem, 'title'),\n description: getComponentData<string>(elem, 'description'),\n settingsSchema: config?.settings?.schema,\n uiSchema: config?.settings?.uiSchema,\n width: config?.layout?.width?.defaultColumns,\n minWidth: config?.layout?.width?.minColumns,\n maxWidth: config?.layout?.width?.maxColumns,\n height: config?.layout?.height?.defaultRows,\n minHeight: config?.layout?.height?.minRows,\n maxHeight: config?.layout?.height?.maxRows,\n }),\n ];\n });\n};\n\n/**\n * A component that allows customizing components in home grid layout.\n *\n * @public\n */\nexport const CustomHomepageGrid = (props: CustomHomepageGridProps) => {\n const styles = useStyles();\n const theme = useTheme();\n const availableWidgets = useElementFilter(\n props.children,\n availableWidgetsFilter,\n [props],\n );\n const defaultLayout = useMemo(() => {\n return props.config\n ? convertConfigToDefaultWidgets(props.config, availableWidgets)\n : [];\n }, [props.config, availableWidgets]);\n const [storedWidgets, storeWidgets, isStorageLoading] =\n useHomeStorage(defaultLayout);\n const [widgets, setWidgets] = useState(storedWidgets);\n\n const preventDuplicateWidgets = props.preventDuplicateWidgets ?? false;\n\n const [addWidgetDialogOpen, setAddWidgetDialogOpen] = useState(false);\n const editModeOn = widgets.find(w => w.layout.isResizable) !== undefined;\n const [editMode, setEditMode] = useState(editModeOn);\n\n useEffect(() => {\n setWidgets(storedWidgets);\n }, [storedWidgets]);\n\n const getWidgetByName = (name: string) => {\n return availableWidgets.find(widget => widget.name === name);\n };\n\n const getWidgetNameFromKey = (key: string) => {\n return key.split('__')[0];\n };\n const { t } = useTranslationRef(homeTranslationRef);\n\n const getAvailableWidgets = () => {\n if (!preventDuplicateWidgets) {\n return availableWidgets;\n }\n const usedWidgetNames = new Set(\n widgets.map(w => getWidgetNameFromKey(w.id)),\n );\n return availableWidgets.filter(widget => !usedWidgetNames.has(widget.name));\n };\n\n const handleAdd = (widget: Widget) => {\n const widgetId = `${widget.name}__${widgets.length + 1}${Math.random()\n .toString(36)\n .slice(2)}`;\n\n setWidgets([\n ...widgets,\n {\n id: widgetId,\n layout: {\n i: widgetId,\n x: 0,\n y: Math.max(...widgets.map(w => w.layout.y + w.layout.h)) + 1,\n w: Math.min(widget.maxWidth ?? Number.MAX_VALUE, widget.width ?? 12),\n h: Math.min(widget.maxHeight ?? Number.MAX_VALUE, widget.height ?? 4),\n minW: widget.minWidth,\n maxW: widget.maxWidth,\n minH: widget.minHeight,\n maxH: widget.maxHeight,\n isResizable: editMode,\n isDraggable: editMode,\n },\n settings: {},\n movable: widget.movable,\n deletable: widget.deletable,\n resizable: widget.resizable,\n },\n ]);\n setAddWidgetDialogOpen(false);\n };\n\n const handleRemove = (widgetId: string) => {\n setWidgets(widgets.filter(w => w.id !== widgetId));\n };\n\n const handleSettingsSave = (\n widgetId: string,\n widgetSettings: Record<string, any>,\n ) => {\n const idx = widgets.findIndex(w => w.id === widgetId);\n if (idx >= 0) {\n const widget = widgets[idx];\n widget.settings = widgetSettings;\n widgets[idx] = widget;\n setWidgets(widgets);\n }\n };\n\n const clearLayout = () => {\n setWidgets(widgets.filter(w => w.deletable === false));\n };\n\n const changeEditMode = (mode: boolean) => {\n setEditMode(mode);\n\n const newWidgets = widgets.map(w => {\n const resizable = w.resizable === false ? false : mode;\n const movable = w.movable === false ? false : mode;\n return {\n ...w,\n layout: { ...w.layout, isDraggable: movable, isResizable: resizable },\n };\n });\n\n if (mode) {\n setWidgets(newWidgets);\n } else {\n storeWidgets(newWidgets);\n }\n };\n\n const handleLayoutChange = (newLayout: Layout[], _: Layouts) => {\n if (editMode) {\n const newWidgets = newLayout.map(l => {\n const widget = widgets.find(w => w.id === l.i);\n return {\n ...widget,\n layout: l,\n } as GridWidget;\n });\n setWidgets(newWidgets);\n }\n };\n\n const handleRestoreDefaultConfig = () => {\n setWidgets(\n defaultLayout.map(w => {\n const resizable = w.resizable === false ? false : editMode;\n const movable = w.movable === false ? false : editMode;\n return {\n ...w,\n layout: {\n ...w.layout,\n isDraggable: movable,\n isResizable: resizable,\n },\n };\n }),\n );\n };\n\n const handleCancel = () => {\n setWidgets(storedWidgets);\n setEditMode(false);\n };\n\n if (isStorageLoading) {\n return <Progress />;\n }\n\n return (\n <>\n <ContentHeader title={props.title}>\n <CustomHomepageButtons\n editMode={editMode}\n numWidgets={widgets.length}\n clearLayout={clearLayout}\n setAddWidgetDialogOpen={setAddWidgetDialogOpen}\n changeEditMode={changeEditMode}\n defaultConfigAvailable={props.config !== undefined}\n restoreDefault={handleRestoreDefaultConfig}\n cancel={handleCancel}\n />\n </ContentHeader>\n <Dialog\n open={addWidgetDialogOpen}\n onClose={() => setAddWidgetDialogOpen(false)}\n >\n {/* Only mount when open so the list does not update (e.g. remove the added widget) before the modal closes */}\n {addWidgetDialogOpen && (\n <AddWidgetDialog\n widgets={getAvailableWidgets()}\n handleAdd={handleAdd}\n />\n )}\n </Dialog>\n {!editMode && widgets.length === 0 && (\n <Typography variant=\"h5\" align=\"center\">\n {t('customHomepage.noWidgets')}\n </Typography>\n )}\n <ResponsiveGrid\n className={styles.responsiveGrid}\n measureBeforeMount\n compactType={props.compactType}\n style={props.style}\n allowOverlap={props.allowOverlap}\n preventCollision={props.preventCollision ?? true}\n draggableCancel=\".overlayGridItem,.widgetSettingsDialog,.disabled\"\n containerPadding={props.containerPadding}\n margin={props.containerMargin}\n breakpoints={\n props.breakpoints ? props.breakpoints : theme.breakpoints.values\n }\n cols={\n props.cols\n ? props.cols\n : { xl: 12, lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }\n }\n rowHeight={props.rowHeight ?? 60}\n onLayoutChange={handleLayoutChange}\n layouts={{ xl: widgets.map(w => w.layout) }}\n >\n {widgets.map((w: GridWidget) => {\n const l = w.layout;\n const widgetName = getWidgetNameFromKey(l.i);\n const widget = getWidgetByName(widgetName);\n if (!widget || !widget.component) {\n return null;\n }\n\n const widgetProps = {\n ...widget.component.props,\n ...(w.settings ?? {}),\n };\n\n return (\n <div\n key={l.i}\n className={`${styles.widgetWrapper} ${editMode && 'edit'} ${\n w.movable === false && 'disabled'\n }`}\n >\n <ErrorBoundary>\n <widget.component.type {...widgetProps} />\n </ErrorBoundary>\n {editMode && (\n <>\n <Typography variant=\"caption\" className={styles.layoutLabel}>\n column: {l.x}, row: {l.y}, width: {l.w}, height: {l.h}\n </Typography>\n <WidgetSettingsOverlay\n id={l.i}\n widget={widget}\n handleRemove={handleRemove}\n handleSettingsSave={handleSettingsSave}\n settings={w.settings}\n deletable={w.deletable}\n />\n </>\n )}\n </div>\n );\n })}\n </ResponsiveGrid>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
|