@backstage/plugin-home 0.9.8-next.0 → 0.9.8
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 +15 -0
- package/README.md +12 -0
- package/dist/alpha.d.ts +1 -0
- package/dist/components/CustomHomepage/AddWidgetDialog.esm.js +2 -1
- package/dist/components/CustomHomepage/AddWidgetDialog.esm.js.map +1 -1
- package/dist/components/CustomHomepage/CustomHomepageGrid.esm.js +17 -1
- package/dist/components/CustomHomepage/CustomHomepageGrid.esm.js.map +1 -1
- package/dist/components/CustomHomepage/types.esm.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/package.json.esm.js +1 -1
- package/dist/translation.esm.js +2 -1
- package/dist/translation.esm.js.map +1 -1
- package/package.json +17 -17
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @backstage/plugin-home
|
|
2
2
|
|
|
3
|
+
## 0.9.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e9776b0: Optionally prevent duplicate widget additions via prop and added empty state for Add Widget dialog
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @backstage/frontend-plugin-api@0.17.3
|
|
10
|
+
- @backstage/plugin-catalog-react@3.2.0
|
|
11
|
+
- @backstage/core-components@0.18.12
|
|
12
|
+
- @backstage/core-app-api@1.20.3
|
|
13
|
+
- @backstage/catalog-client@1.16.1
|
|
14
|
+
- @backstage/core-compat-api@0.5.13
|
|
15
|
+
- @backstage/core-plugin-api@1.12.8
|
|
16
|
+
- @backstage/plugin-home-react@0.1.40
|
|
17
|
+
|
|
3
18
|
## 0.9.8-next.0
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -132,6 +132,18 @@ const myWidget = HomePageWidgetBlueprint.make({
|
|
|
132
132
|
|
|
133
133
|
> **Example**: See [dev/index.tsx](dev/index.tsx) for a comprehensive example of creating multiple homepage widgets and layouts.
|
|
134
134
|
|
|
135
|
+
### Preventing Duplicate Widgets
|
|
136
|
+
|
|
137
|
+
The `CustomHomepageGrid` supports preventing duplicate widgets from being added to the homepage via the `preventDuplicateWidgets` prop (default: `false`):
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
<CustomHomepageGrid preventDuplicateWidgets={true}>
|
|
141
|
+
<HomePageSearchBar />
|
|
142
|
+
<HomePageRandomJoke />
|
|
143
|
+
<HomePageStarredEntities />
|
|
144
|
+
</CustomHomepageGrid>
|
|
145
|
+
```
|
|
146
|
+
|
|
135
147
|
## Contributing
|
|
136
148
|
|
|
137
149
|
### Homepage Components
|
package/dist/alpha.d.ts
CHANGED
|
@@ -120,6 +120,7 @@ declare const _default: _backstage_frontend_plugin_api.OverridableFrontendPlugin
|
|
|
120
120
|
declare const homeTranslationRef: _backstage_frontend_plugin_api.TranslationRef<"home", {
|
|
121
121
|
readonly "starredEntities.noStarredEntitiesMessage": "Click the star beside an entity name to add it to this list!";
|
|
122
122
|
readonly "addWidgetDialog.title": "Add new widget to dashboard";
|
|
123
|
+
readonly "addWidgetDialog.noAvailableWidgets": "All available widgets have been added to the dashboard.";
|
|
123
124
|
readonly "customHomepageButtons.cancel": "Cancel";
|
|
124
125
|
readonly "customHomepageButtons.clearAll": "Clear all";
|
|
125
126
|
readonly "customHomepageButtons.edit": "Edit";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import Box from '@material-ui/core/Box';
|
|
2
3
|
import List from '@material-ui/core/List';
|
|
3
4
|
import ListItem from '@material-ui/core/ListItem';
|
|
4
5
|
import DialogContent from '@material-ui/core/DialogContent';
|
|
@@ -18,7 +19,7 @@ const AddWidgetDialog = (props) => {
|
|
|
18
19
|
const { t } = useTranslationRef(homeTranslationRef);
|
|
19
20
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
20
21
|
/* @__PURE__ */ jsx(DialogTitle, { children: t("addWidgetDialog.title") }),
|
|
21
|
-
/* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsx(List, { dense: true, children: widgets.map((widget) => {
|
|
22
|
+
/* @__PURE__ */ jsx(DialogContent, { children: widgets.length === 0 ? /* @__PURE__ */ jsx(Box, { pb: 3, textAlign: "center", children: /* @__PURE__ */ jsx(Typography, { variant: "body1", color: "textSecondary", children: t("addWidgetDialog.noAvailableWidgets") }) }) : /* @__PURE__ */ jsx(List, { dense: true, children: widgets.map((widget) => {
|
|
22
23
|
return /* @__PURE__ */ jsxs(
|
|
23
24
|
ListItem,
|
|
24
25
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AddWidgetDialog.esm.js","sources":["../../../src/components/CustomHomepage/AddWidgetDialog.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 { Widget } from './types';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport ListItemAvatar from '@material-ui/core/ListItemAvatar';\nimport AddIcon from '@material-ui/icons/Add';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport Typography from '@material-ui/core/Typography';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport { homeTranslationRef } from '../../translation';\n\ninterface AddWidgetDialogProps {\n widgets: Widget[];\n handleAdd: (widget: Widget) => void;\n}\n\nconst getTitle = (widget: Widget) => {\n return widget.title || widget.name;\n};\n\nexport const AddWidgetDialog = (props: AddWidgetDialogProps) => {\n const { widgets, handleAdd } = props;\n const { t } = useTranslationRef(homeTranslationRef);\n return (\n <>\n <DialogTitle>{t('addWidgetDialog.title')}</DialogTitle>\n <DialogContent>\n <List dense>\n
|
|
1
|
+
{"version":3,"file":"AddWidgetDialog.esm.js","sources":["../../../src/components/CustomHomepage/AddWidgetDialog.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 { Widget } from './types';\nimport Box from '@material-ui/core/Box';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport ListItemAvatar from '@material-ui/core/ListItemAvatar';\nimport AddIcon from '@material-ui/icons/Add';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport Typography from '@material-ui/core/Typography';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport { homeTranslationRef } from '../../translation';\n\ninterface AddWidgetDialogProps {\n widgets: Widget[];\n handleAdd: (widget: Widget) => void;\n}\n\nconst getTitle = (widget: Widget) => {\n return widget.title || widget.name;\n};\n\nexport const AddWidgetDialog = (props: AddWidgetDialogProps) => {\n const { widgets, handleAdd } = props;\n const { t } = useTranslationRef(homeTranslationRef);\n return (\n <>\n <DialogTitle>{t('addWidgetDialog.title')}</DialogTitle>\n <DialogContent>\n {widgets.length === 0 ? (\n <Box pb={3} textAlign=\"center\">\n <Typography variant=\"body1\" color=\"textSecondary\">\n {t('addWidgetDialog.noAvailableWidgets')}\n </Typography>\n </Box>\n ) : (\n <List dense>\n {widgets.map(widget => {\n return (\n <ListItem\n key={widget.name}\n button\n onClick={() => handleAdd(widget)}\n >\n <ListItemAvatar>\n <AddIcon />\n </ListItemAvatar>\n <ListItemText\n secondary={\n widget.description && (\n <Typography\n component=\"span\"\n variant=\"caption\"\n color=\"textPrimary\"\n >\n {widget.description}\n </Typography>\n )\n }\n primary={\n <Typography variant=\"body1\" color=\"textPrimary\">\n {getTitle(widget)}\n </Typography>\n }\n />\n </ListItem>\n );\n })}\n </List>\n )}\n </DialogContent>\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;AAkCA,MAAM,QAAA,GAAW,CAAC,MAAA,KAAmB;AACnC,EAAA,OAAO,MAAA,CAAO,SAAS,MAAA,CAAO,IAAA;AAChC,CAAA;AAEO,MAAM,eAAA,GAAkB,CAAC,KAAA,KAAgC;AAC9D,EAAA,MAAM,EAAE,OAAA,EAAS,SAAA,EAAU,GAAI,KAAA;AAC/B,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,kBAAkB,CAAA;AAClD,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,WAAA,EAAA,EAAa,QAAA,EAAA,CAAA,CAAE,uBAAuB,CAAA,EAAE,CAAA;AAAA,oBACzC,GAAA,CAAC,aAAA,EAAA,EACE,QAAA,EAAA,OAAA,CAAQ,MAAA,KAAW,CAAA,mBAClB,GAAA,CAAC,GAAA,EAAA,EAAI,EAAA,EAAI,CAAA,EAAG,SAAA,EAAU,QAAA,EACpB,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,OAAA,EAAQ,KAAA,EAAM,eAAA,EAC/B,QAAA,EAAA,CAAA,CAAE,oCAAoC,CAAA,EACzC,CAAA,EACF,CAAA,mBAEA,GAAA,CAAC,IAAA,EAAA,EAAK,KAAA,EAAK,IAAA,EACR,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,MAAA,KAAU;AACrB,MAAA,uBACE,IAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UAEC,MAAA,EAAM,IAAA;AAAA,UACN,OAAA,EAAS,MAAM,SAAA,CAAU,MAAM,CAAA;AAAA,UAE/B,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,cAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,OAAA,EAAA,EAAQ,CAAA,EACX,CAAA;AAAA,4BACA,GAAA;AAAA,cAAC,YAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EACE,OAAO,WAAA,oBACL,GAAA;AAAA,kBAAC,UAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAU,MAAA;AAAA,oBACV,OAAA,EAAQ,SAAA;AAAA,oBACR,KAAA,EAAM,aAAA;AAAA,oBAEL,QAAA,EAAA,MAAA,CAAO;AAAA;AAAA,iBACV;AAAA,gBAGJ,OAAA,sBACG,UAAA,EAAA,EAAW,OAAA,EAAQ,SAAQ,KAAA,EAAM,aAAA,EAC/B,QAAA,EAAA,QAAA,CAAS,MAAM,CAAA,EAClB;AAAA;AAAA;AAEJ;AAAA,SAAA;AAAA,QAxBK,MAAA,CAAO;AAAA,OAyBd;AAAA,IAEJ,CAAC,GACH,CAAA,EAEJ;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}
|
|
@@ -153,6 +153,7 @@ const CustomHomepageGrid = (props) => {
|
|
|
153
153
|
}, [props.config, availableWidgets]);
|
|
154
154
|
const [storedWidgets, storeWidgets, isStorageLoading] = useHomeStorage(defaultLayout);
|
|
155
155
|
const [widgets, setWidgets] = useState(storedWidgets);
|
|
156
|
+
const preventDuplicateWidgets = props.preventDuplicateWidgets ?? false;
|
|
156
157
|
const [addWidgetDialogOpen, setAddWidgetDialogOpen] = useState(false);
|
|
157
158
|
const editModeOn = widgets.find((w) => w.layout.isResizable) !== void 0;
|
|
158
159
|
const [editMode, setEditMode] = useState(editModeOn);
|
|
@@ -166,6 +167,15 @@ const CustomHomepageGrid = (props) => {
|
|
|
166
167
|
return key.split("__")[0];
|
|
167
168
|
};
|
|
168
169
|
const { t } = useTranslationRef(homeTranslationRef);
|
|
170
|
+
const getAvailableWidgets = () => {
|
|
171
|
+
if (!preventDuplicateWidgets) {
|
|
172
|
+
return availableWidgets;
|
|
173
|
+
}
|
|
174
|
+
const usedWidgetNames = new Set(
|
|
175
|
+
widgets.map((w) => getWidgetNameFromKey(w.id))
|
|
176
|
+
);
|
|
177
|
+
return availableWidgets.filter((widget) => !usedWidgetNames.has(widget.name));
|
|
178
|
+
};
|
|
169
179
|
const handleAdd = (widget) => {
|
|
170
180
|
const widgetId = `${widget.name}__${widgets.length + 1}${Math.random().toString(36).slice(2)}`;
|
|
171
181
|
setWidgets([
|
|
@@ -278,7 +288,13 @@ const CustomHomepageGrid = (props) => {
|
|
|
278
288
|
{
|
|
279
289
|
open: addWidgetDialogOpen,
|
|
280
290
|
onClose: () => setAddWidgetDialogOpen(false),
|
|
281
|
-
children: /* @__PURE__ */ jsx(
|
|
291
|
+
children: addWidgetDialogOpen && /* @__PURE__ */ jsx(
|
|
292
|
+
AddWidgetDialog,
|
|
293
|
+
{
|
|
294
|
+
widgets: getAvailableWidgets(),
|
|
295
|
+
handleAdd
|
|
296
|
+
}
|
|
297
|
+
)
|
|
282
298
|
}
|
|
283
299
|
),
|
|
284
300
|
!editMode && widgets.length === 0 && /* @__PURE__ */ jsx(Typography, { variant: "h5", align: "center", children: t("customHomepage.noWidgets") }),
|
|
@@ -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 [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 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 <AddWidgetDialog widgets={availableWidgets} handleAdd={handleAdd} />\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 }),\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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.esm.js","sources":["../../../src/components/CustomHomepage/types.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 { CSSProperties, ReactElement, ReactNode } from 'react';\nimport { Layout } from 'react-grid-layout';\nimport { z } from 'zod/v3';\nimport { RJSFSchema, UiSchema } from '@rjsf/utils';\n\nconst RSJFTypeSchema: z.ZodType<RJSFSchema> = z.any();\nconst RSJFTypeUiSchema: z.ZodType<UiSchema> = z.any();\nconst ReactElementSchema: z.ZodType<ReactElement> = z.any();\nconst LayoutSchema: z.ZodType<Layout> = z.any();\n\n/**\n * Breakpoint options for <CustomHomepageGridProps/>\n *\n * @public\n */\nexport type Breakpoint = 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\n/**\n * Props customizing the <CustomHomepageGrid/> component.\n *\n * @public\n */\nexport type CustomHomepageGridProps = {\n /**\n * Children contain all widgets user can configure on their own homepage.\n */\n children?: ReactNode;\n /**\n * Default layout for the homepage before users have modified it.\n */\n config?: LayoutConfiguration[];\n /**\n * Title displayed in the header of the grid. If not provided, no title will be shown.\n */\n title?: string;\n /**\n * Height of grid row in pixels.\n * @defaultValue 60\n */\n rowHeight?: number;\n /**\n * Screen width in pixels for different breakpoints.\n * @defaultValue theme breakpoints\n */\n breakpoints?: Record<Breakpoint, number>;\n /**\n * Number of grid columns for different breakpoints.\n * @defaultValue \\{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 \\}\n */\n cols?: Record<Breakpoint, number>;\n /**\n * Grid container padding (x, y) in pixels for all or specific breakpoints.\n * @defaultValue [0, 0]\n * @example [10, 10]\n * @example \\{ lg: [10, 10] \\}\n */\n containerPadding?: [number, number] | Record<Breakpoint, [number, number]>;\n /**\n * Grid container margin (x, y) in pixels for all or specific breakpoints.\n * @defaultValue [0, 0]\n * @example [10, 10]\n * @example \\{ lg: [10, 10] \\}\n */\n containerMargin?: [number, number] | Record<Breakpoint, [number, number]>;\n /**\n * Maximum number of rows user can have in the grid.\n * @defaultValue unlimited\n */\n maxRows?: number;\n /**\n * Custom style for grid.\n */\n style?: CSSProperties;\n /**\n * Compaction type of widgets in the grid. This controls where widgets are moved in case\n * they are overlapping in the grid.\n */\n compactType?: 'vertical' | 'horizontal' | null;\n /**\n * Controls if widgets can overlap in the grid. If true, grid can be placed one over the other.\n * @defaultValue false\n */\n allowOverlap?: boolean;\n /**\n * Controls if widgets can collide with each other. If true, grid items won't change position when being dragged over.\n * @defaultValue true\n */\n preventCollision?: boolean;\n};\n\nexport const LayoutConfigurationSchema = z.object({\n component: ReactElementSchema,\n x: z.number().nonnegative('x must be positive number'),\n y: z.number().nonnegative('y must be positive number'),\n width: z.number().positive('width must be positive number'),\n height: z.number().positive('height must be positive number'),\n movable: z.boolean().optional(),\n deletable: z.boolean().optional(),\n resizable: z.boolean().optional(),\n});\n\n/**\n * Layout configuration that can be passed to the custom home page.\n *\n * @public\n */\nexport type LayoutConfiguration = {\n component: ReactElement | string;\n x: number;\n y: number;\n width: number;\n height: number;\n movable?: boolean;\n deletable?: boolean;\n resizable?: boolean;\n};\n\nexport const WidgetSchema = z.object({\n name: z.string(),\n title: z.string().optional(),\n description: z.string().optional(),\n component: ReactElementSchema,\n width: z.number().positive('width must be positive number').optional(),\n height: z.number().positive('height must be positive number').optional(),\n minWidth: z.number().positive('minWidth must be positive number').optional(),\n maxWidth: z.number().positive('maxWidth must be positive number').optional(),\n minHeight: z\n .number()\n .positive('minHeight must be positive number')\n .optional(),\n maxHeight: z\n .number()\n .positive('maxHeight must be positive number')\n .optional(),\n settingsSchema: RSJFTypeSchema.optional(),\n uiSchema: RSJFTypeUiSchema.optional(),\n movable: z.boolean().optional(),\n deletable: z.boolean().optional(),\n resizable: z.boolean().optional(),\n});\n\nexport type Widget = z.infer<typeof WidgetSchema>;\n\nconst GridWidgetSchema = z.object({\n id: z.string(),\n layout: LayoutSchema,\n settings: z.record(z.string(), z.any()),\n movable: z.boolean().optional(),\n deletable: z.boolean().optional(),\n resizable: z.boolean().optional(),\n});\n\nexport type GridWidget = z.infer<typeof GridWidgetSchema>;\n\nexport const CustomHomepageGridStateV1Schema = z.object({\n version: z.literal(1),\n pages: z.record(z.string(), z.array(GridWidgetSchema)),\n});\n\nexport type CustomHomepageGridStateV1 = z.infer<\n typeof CustomHomepageGridStateV1Schema\n>;\n"],"names":[],"mappings":";;AAqBA,MAAM,cAAA,GAAwC,EAAE,GAAA,EAAI;AACpD,MAAM,gBAAA,GAAwC,EAAE,GAAA,EAAI;AACpD,MAAM,kBAAA,GAA8C,EAAE,GAAA,EAAI;AAC1D,MAAM,YAAA,GAAkC,EAAE,GAAA,EAAI;
|
|
1
|
+
{"version":3,"file":"types.esm.js","sources":["../../../src/components/CustomHomepage/types.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 { CSSProperties, ReactElement, ReactNode } from 'react';\nimport { Layout } from 'react-grid-layout';\nimport { z } from 'zod/v3';\nimport { RJSFSchema, UiSchema } from '@rjsf/utils';\n\nconst RSJFTypeSchema: z.ZodType<RJSFSchema> = z.any();\nconst RSJFTypeUiSchema: z.ZodType<UiSchema> = z.any();\nconst ReactElementSchema: z.ZodType<ReactElement> = z.any();\nconst LayoutSchema: z.ZodType<Layout> = z.any();\n\n/**\n * Breakpoint options for <CustomHomepageGridProps/>\n *\n * @public\n */\nexport type Breakpoint = 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\n/**\n * Props customizing the <CustomHomepageGrid/> component.\n *\n * @public\n */\nexport type CustomHomepageGridProps = {\n /**\n * Children contain all widgets user can configure on their own homepage.\n */\n children?: ReactNode;\n /**\n * Default layout for the homepage before users have modified it.\n */\n config?: LayoutConfiguration[];\n /**\n * Title displayed in the header of the grid. If not provided, no title will be shown.\n */\n title?: string;\n /**\n * Height of grid row in pixels.\n * @defaultValue 60\n */\n rowHeight?: number;\n /**\n * Screen width in pixels for different breakpoints.\n * @defaultValue theme breakpoints\n */\n breakpoints?: Record<Breakpoint, number>;\n /**\n * Number of grid columns for different breakpoints.\n * @defaultValue \\{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 \\}\n */\n cols?: Record<Breakpoint, number>;\n /**\n * Grid container padding (x, y) in pixels for all or specific breakpoints.\n * @defaultValue [0, 0]\n * @example [10, 10]\n * @example \\{ lg: [10, 10] \\}\n */\n containerPadding?: [number, number] | Record<Breakpoint, [number, number]>;\n /**\n * Grid container margin (x, y) in pixels for all or specific breakpoints.\n * @defaultValue [0, 0]\n * @example [10, 10]\n * @example \\{ lg: [10, 10] \\}\n */\n containerMargin?: [number, number] | Record<Breakpoint, [number, number]>;\n /**\n * Maximum number of rows user can have in the grid.\n * @defaultValue unlimited\n */\n maxRows?: number;\n /**\n * Custom style for grid.\n */\n style?: CSSProperties;\n /**\n * Compaction type of widgets in the grid. This controls where widgets are moved in case\n * they are overlapping in the grid.\n */\n compactType?: 'vertical' | 'horizontal' | null;\n /**\n * Controls if widgets can overlap in the grid. If true, grid can be placed one over the other.\n * @defaultValue false\n */\n allowOverlap?: boolean;\n /**\n * Controls if widgets can collide with each other. If true, grid items won't change position when being dragged over.\n * @defaultValue true\n */\n preventCollision?: boolean;\n /**\n * Controls if widgets can be added to the grid if they already exist. If true, widgets already present on the grid are excluded from the Add Widget dialog (preventing duplicates)\n * @defaultValue false\n */\n preventDuplicateWidgets?: boolean;\n};\n\nexport const LayoutConfigurationSchema = z.object({\n component: ReactElementSchema,\n x: z.number().nonnegative('x must be positive number'),\n y: z.number().nonnegative('y must be positive number'),\n width: z.number().positive('width must be positive number'),\n height: z.number().positive('height must be positive number'),\n movable: z.boolean().optional(),\n deletable: z.boolean().optional(),\n resizable: z.boolean().optional(),\n});\n\n/**\n * Layout configuration that can be passed to the custom home page.\n *\n * @public\n */\nexport type LayoutConfiguration = {\n component: ReactElement | string;\n x: number;\n y: number;\n width: number;\n height: number;\n movable?: boolean;\n deletable?: boolean;\n resizable?: boolean;\n};\n\nexport const WidgetSchema = z.object({\n name: z.string(),\n title: z.string().optional(),\n description: z.string().optional(),\n component: ReactElementSchema,\n width: z.number().positive('width must be positive number').optional(),\n height: z.number().positive('height must be positive number').optional(),\n minWidth: z.number().positive('minWidth must be positive number').optional(),\n maxWidth: z.number().positive('maxWidth must be positive number').optional(),\n minHeight: z\n .number()\n .positive('minHeight must be positive number')\n .optional(),\n maxHeight: z\n .number()\n .positive('maxHeight must be positive number')\n .optional(),\n settingsSchema: RSJFTypeSchema.optional(),\n uiSchema: RSJFTypeUiSchema.optional(),\n movable: z.boolean().optional(),\n deletable: z.boolean().optional(),\n resizable: z.boolean().optional(),\n});\n\nexport type Widget = z.infer<typeof WidgetSchema>;\n\nconst GridWidgetSchema = z.object({\n id: z.string(),\n layout: LayoutSchema,\n settings: z.record(z.string(), z.any()),\n movable: z.boolean().optional(),\n deletable: z.boolean().optional(),\n resizable: z.boolean().optional(),\n});\n\nexport type GridWidget = z.infer<typeof GridWidgetSchema>;\n\nexport const CustomHomepageGridStateV1Schema = z.object({\n version: z.literal(1),\n pages: z.record(z.string(), z.array(GridWidgetSchema)),\n});\n\nexport type CustomHomepageGridStateV1 = z.infer<\n typeof CustomHomepageGridStateV1Schema\n>;\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -479,6 +479,11 @@ type CustomHomepageGridProps = {
|
|
|
479
479
|
* @defaultValue true
|
|
480
480
|
*/
|
|
481
481
|
preventCollision?: boolean;
|
|
482
|
+
/**
|
|
483
|
+
* Controls if widgets can be added to the grid if they already exist. If true, widgets already present on the grid are excluded from the Add Widget dialog (preventing duplicates)
|
|
484
|
+
* @defaultValue false
|
|
485
|
+
*/
|
|
486
|
+
preventDuplicateWidgets?: boolean;
|
|
482
487
|
};
|
|
483
488
|
/**
|
|
484
489
|
* Layout configuration that can be passed to the custom home page.
|
|
@@ -627,6 +632,7 @@ declare const SettingsModal: (props: {
|
|
|
627
632
|
declare const homeTranslationRef: _backstage_frontend_plugin_api.TranslationRef<"home", {
|
|
628
633
|
readonly "starredEntities.noStarredEntitiesMessage": "Click the star beside an entity name to add it to this list!";
|
|
629
634
|
readonly "addWidgetDialog.title": "Add new widget to dashboard";
|
|
635
|
+
readonly "addWidgetDialog.noAvailableWidgets": "All available widgets have been added to the dashboard.";
|
|
630
636
|
readonly "customHomepageButtons.cancel": "Cancel";
|
|
631
637
|
readonly "customHomepageButtons.clearAll": "Clear all";
|
|
632
638
|
readonly "customHomepageButtons.edit": "Edit";
|
package/dist/package.json.esm.js
CHANGED
package/dist/translation.esm.js
CHANGED
|
@@ -4,7 +4,8 @@ const homeTranslationRef = createTranslationRef({
|
|
|
4
4
|
id: "home",
|
|
5
5
|
messages: {
|
|
6
6
|
addWidgetDialog: {
|
|
7
|
-
title: "Add new widget to dashboard"
|
|
7
|
+
title: "Add new widget to dashboard",
|
|
8
|
+
noAvailableWidgets: "All available widgets have been added to the dashboard."
|
|
8
9
|
},
|
|
9
10
|
customHomepageButtons: {
|
|
10
11
|
edit: "Edit",
|
|
@@ -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 * Translation reference for the home plugin.\n * Contains localized text strings for home page components and widgets.\n *\n * @public\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 editSettingsTooltip: 'Edit settings',\n /**\n * @deprecated Use `editSettingsTooltip` instead. This was a typo in the original key.\n */\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,
|
|
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 * @public\n */\nexport const homeTranslationRef = createTranslationRef({\n id: 'home',\n messages: {\n addWidgetDialog: {\n title: 'Add new widget to dashboard',\n noAvailableWidgets:\n 'All available widgets have been added to the 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 editSettingsTooltip: 'Edit settings',\n /**\n * @deprecated Use `editSettingsTooltip` instead. This was a typo in the original key.\n */\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,6BAAA;AAAA,MACP,kBAAA,EACE;AAAA,KACJ;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;AAAA;AAAA;AAAA,MAIrB,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.8
|
|
3
|
+
"version": "0.9.8",
|
|
4
4
|
"description": "A Backstage plugin that helps you build a home page",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "frontend-plugin",
|
|
@@ -68,17 +68,17 @@
|
|
|
68
68
|
"test": "backstage-cli package test"
|
|
69
69
|
},
|
|
70
70
|
"dependencies": {
|
|
71
|
-
"@backstage/catalog-client": "1.16.1
|
|
72
|
-
"@backstage/catalog-model": "1.9.0",
|
|
73
|
-
"@backstage/config": "1.3.8",
|
|
74
|
-
"@backstage/core-app-api": "1.20.3
|
|
75
|
-
"@backstage/core-compat-api": "0.5.13
|
|
76
|
-
"@backstage/core-components": "0.18.12
|
|
77
|
-
"@backstage/core-plugin-api": "1.12.8
|
|
78
|
-
"@backstage/frontend-plugin-api": "0.17.3
|
|
79
|
-
"@backstage/plugin-catalog-react": "3.2.0
|
|
80
|
-
"@backstage/plugin-home-react": "0.1.40
|
|
81
|
-
"@backstage/theme": "0.7.3",
|
|
71
|
+
"@backstage/catalog-client": "^1.16.1",
|
|
72
|
+
"@backstage/catalog-model": "^1.9.0",
|
|
73
|
+
"@backstage/config": "^1.3.8",
|
|
74
|
+
"@backstage/core-app-api": "^1.20.3",
|
|
75
|
+
"@backstage/core-compat-api": "^0.5.13",
|
|
76
|
+
"@backstage/core-components": "^0.18.12",
|
|
77
|
+
"@backstage/core-plugin-api": "^1.12.8",
|
|
78
|
+
"@backstage/frontend-plugin-api": "^0.17.3",
|
|
79
|
+
"@backstage/plugin-catalog-react": "^3.2.0",
|
|
80
|
+
"@backstage/plugin-home-react": "^0.1.40",
|
|
81
|
+
"@backstage/theme": "^0.7.3",
|
|
82
82
|
"@material-ui/core": "^4.12.2",
|
|
83
83
|
"@material-ui/icons": "^4.9.1",
|
|
84
84
|
"@material-ui/lab": "4.0.0-alpha.61",
|
|
@@ -94,11 +94,11 @@
|
|
|
94
94
|
"zod": "^3.25.76 || ^4.0.0"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
|
-
"@backstage/cli": "0.36.4
|
|
98
|
-
"@backstage/dev-utils": "1.1.25
|
|
99
|
-
"@backstage/frontend-defaults": "0.5.4
|
|
100
|
-
"@backstage/plugin-catalog": "2.0.7
|
|
101
|
-
"@backstage/test-utils": "1.7.20
|
|
97
|
+
"@backstage/cli": "^0.36.4",
|
|
98
|
+
"@backstage/dev-utils": "^1.1.25",
|
|
99
|
+
"@backstage/frontend-defaults": "^0.5.4",
|
|
100
|
+
"@backstage/plugin-catalog": "^2.0.7",
|
|
101
|
+
"@backstage/test-utils": "^1.7.20",
|
|
102
102
|
"@testing-library/dom": "^10.0.0",
|
|
103
103
|
"@testing-library/jest-dom": "^6.0.0",
|
|
104
104
|
"@testing-library/react": "^16.0.0",
|