@backstage/plugin-home 0.8.8-next.2 → 0.8.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 CHANGED
@@ -1,5 +1,62 @@
1
1
  # @backstage/plugin-home
2
2
 
3
+ ## 0.8.8
4
+
5
+ ### Patch Changes
6
+
7
+ - f7ca0fe: Added the Catalog presentation API to the HomePageRecentlyVisited and HomePageTopVisited components
8
+ - fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`.
9
+ - eddd96c: Added optional title prop to `customHomePageGrid`
10
+ - 16eb4bf: Export ContentModal from `@backstage/plugin-home-react` so people can use this in other scenarios.
11
+ Renamed `CatalogReactComponentsNameToClassKey` to `PluginHomeComponentsNameToClassKey` in `overridableComponents.ts`
12
+
13
+ Made QuickStartCard `docsLinkTitle` prop more flexible to allow for any React.JSX.Element instead of just a string.
14
+ Added QuickStartCard prop `additionalContent` which can eventually replace the prop `video`.
15
+
16
+ - 2c1761f: Added a `variant` prop to the `WelcomeTitle` component making it work with the Customizable Home page feature. Adding it like this `<WelcomeTitle variant='h1' />` to the list of items under `CustomHomepageGrid` will allow it to render with a size that works well.
17
+ - 195323f: Export root page route from the home plugin to enable adding links/nav to it from outside the plugin
18
+ - 72d019d: Removed various typos
19
+ - d710d74: docs: Update default for `preventCollision` prop
20
+ - Updated dependencies
21
+ - @backstage/frontend-plugin-api@0.10.2
22
+ - @backstage/theme@0.6.6
23
+ - @backstage/core-app-api@1.17.0
24
+ - @backstage/core-components@0.17.2
25
+ - @backstage/catalog-model@1.7.4
26
+ - @backstage/core-compat-api@0.4.2
27
+ - @backstage/plugin-home-react@0.1.26
28
+ - @backstage/plugin-catalog-react@1.18.0
29
+ - @backstage/core-plugin-api@1.10.7
30
+ - @backstage/catalog-client@1.10.0
31
+ - @backstage/config@1.3.2
32
+
33
+ ## 0.8.8-next.3
34
+
35
+ ### Patch Changes
36
+
37
+ - f7ca0fe: Added the Catalog presentation API to the HomePageRecentlyVisited and HomePageTopVisited components
38
+ - eddd96c: Added optional title prop to `customHomePageGrid`
39
+ - 16eb4bf: Export ContentModal from `@backstage/plugin-home-react` so people can use this in other scenarios.
40
+ Renamed `CatalogReactComponentsNameToClassKey` to `PluginHomeComponentsNameToClassKey` in `overridableComponents.ts`
41
+
42
+ Made QuickStartCard `docsLinkTitle` prop more flexible to allow for any React.JSX.Element instead of just a string.
43
+ Added QuickStartCard prop `additionalContent` which can eventually replace the prop `video`.
44
+
45
+ - 195323f: Export root page route from the home plugin to enable adding links/nav to it from outside the plugin
46
+ - d710d74: docs: Update default for `preventCollision` prop
47
+ - Updated dependencies
48
+ - @backstage/core-app-api@1.17.0-next.1
49
+ - @backstage/plugin-home-react@0.1.26-next.2
50
+ - @backstage/core-compat-api@0.4.2-next.3
51
+ - @backstage/core-components@0.17.2-next.1
52
+ - @backstage/core-plugin-api@1.10.7-next.0
53
+ - @backstage/plugin-catalog-react@1.18.0-next.3
54
+ - @backstage/catalog-client@1.10.0-next.0
55
+ - @backstage/catalog-model@1.7.3
56
+ - @backstage/config@1.3.2
57
+ - @backstage/frontend-plugin-api@0.10.2-next.1
58
+ - @backstage/theme@0.6.6-next.0
59
+
3
60
  ## 0.8.8-next.2
4
61
 
5
62
  ### Patch Changes
package/README.md CHANGED
@@ -107,6 +107,9 @@ export const homePage = (
107
107
  );
108
108
  ```
109
109
 
110
+ > [!NOTE]
111
+ > You can provide a title to the grid by passing it as a prop: `<CustomHomepageGrid title="Your Dashboard" />`. This will be displayed as a header above the grid layout.
112
+
110
113
  ### Creating Customizable Components
111
114
 
112
115
  The custom home page can use the default components created by using the default `createCardExtension` method but if you
package/dist/alpha.d.ts CHANGED
@@ -8,7 +8,9 @@ declare const titleExtensionDataRef: _backstage_frontend_plugin_api.Configurable
8
8
  /**
9
9
  * @alpha
10
10
  */
11
- declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{}, {}, {
11
+ declare const _default: _backstage_frontend_plugin_api.FrontendPlugin<{
12
+ root: _backstage_frontend_plugin_api.RouteRef<undefined>;
13
+ }, {}, {
12
14
  "page:home": _backstage_frontend_plugin_api.ExtensionDefinition<{
13
15
  config: {
14
16
  path: string | undefined;
package/dist/alpha.esm.js CHANGED
@@ -39,7 +39,10 @@ const homePage = PageBlueprint.makeWithOverrides({
39
39
  });
40
40
  var alpha = createFrontendPlugin({
41
41
  pluginId: "home",
42
- extensions: [homePage]
42
+ extensions: [homePage],
43
+ routes: {
44
+ root: rootRouteRef
45
+ }
43
46
  });
44
47
 
45
48
  export { alpha as default, titleExtensionDataRef };
@@ -1 +1 @@
1
- {"version":3,"file":"alpha.esm.js","sources":["../src/alpha.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreExtensionData,\n createExtensionDataRef,\n createExtensionInput,\n PageBlueprint,\n createFrontendPlugin,\n createRouteRef,\n} from '@backstage/frontend-plugin-api';\nimport { compatWrapper } from '@backstage/core-compat-api';\n\nconst rootRouteRef = createRouteRef();\n\n/**\n * @alpha\n */\nexport const titleExtensionDataRef = createExtensionDataRef<string>().with({\n id: 'title',\n});\n\nconst homePage = PageBlueprint.makeWithOverrides({\n inputs: {\n props: createExtensionInput(\n [\n coreExtensionData.reactElement.optional(),\n titleExtensionDataRef.optional(),\n ],\n {\n singleton: true,\n optional: true,\n },\n ),\n },\n factory: (originalFactory, { inputs }) => {\n return originalFactory({\n defaultPath: '/home',\n routeRef: rootRouteRef,\n loader: () =>\n import('./components/').then(m =>\n compatWrapper(\n <m.HomepageCompositionRoot\n children={inputs.props?.get(coreExtensionData.reactElement)}\n title={inputs.props?.get(titleExtensionDataRef)}\n />,\n ),\n ),\n });\n },\n});\n\n/**\n * @alpha\n */\nexport default createFrontendPlugin({\n pluginId: 'home',\n extensions: [homePage],\n});\n"],"names":[],"mappings":";;;;AA0BA,MAAM,eAAe,cAAe,EAAA;AAKvB,MAAA,qBAAA,GAAwB,sBAA+B,EAAA,CAAE,IAAK,CAAA;AAAA,EACzE,EAAI,EAAA;AACN,CAAC;AAED,MAAM,QAAA,GAAW,cAAc,iBAAkB,CAAA;AAAA,EAC/C,MAAQ,EAAA;AAAA,IACN,KAAO,EAAA,oBAAA;AAAA,MACL;AAAA,QACE,iBAAA,CAAkB,aAAa,QAAS,EAAA;AAAA,QACxC,sBAAsB,QAAS;AAAA,OACjC;AAAA,MACA;AAAA,QACE,SAAW,EAAA,IAAA;AAAA,QACX,QAAU,EAAA;AAAA;AACZ;AACF,GACF;AAAA,EACA,OAAS,EAAA,CAAC,eAAiB,EAAA,EAAE,QAAa,KAAA;AACxC,IAAA,OAAO,eAAgB,CAAA;AAAA,MACrB,WAAa,EAAA,OAAA;AAAA,MACb,QAAU,EAAA,YAAA;AAAA,MACV,MAAQ,EAAA,MACN,OAAO,2BAAe,CAAE,CAAA,IAAA;AAAA,QAAK,CAC3B,CAAA,KAAA,aAAA;AAAA,0BACE,GAAA;AAAA,YAAC,CAAE,CAAA,uBAAA;AAAA,YAAF;AAAA,cACC,QAAU,EAAA,MAAA,CAAO,KAAO,EAAA,GAAA,CAAI,kBAAkB,YAAY,CAAA;AAAA,cAC1D,KAAO,EAAA,MAAA,CAAO,KAAO,EAAA,GAAA,CAAI,qBAAqB;AAAA;AAAA;AAChD;AACF;AACF,KACH,CAAA;AAAA;AAEL,CAAC,CAAA;AAKD,YAAe,oBAAqB,CAAA;AAAA,EAClC,QAAU,EAAA,MAAA;AAAA,EACV,UAAA,EAAY,CAAC,QAAQ;AACvB,CAAC,CAAA;;;;"}
1
+ {"version":3,"file":"alpha.esm.js","sources":["../src/alpha.tsx"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreExtensionData,\n createExtensionDataRef,\n createExtensionInput,\n PageBlueprint,\n createFrontendPlugin,\n createRouteRef,\n} from '@backstage/frontend-plugin-api';\nimport { compatWrapper } from '@backstage/core-compat-api';\n\nconst rootRouteRef = createRouteRef();\n\n/**\n * @alpha\n */\nexport const titleExtensionDataRef = createExtensionDataRef<string>().with({\n id: 'title',\n});\n\nconst homePage = PageBlueprint.makeWithOverrides({\n inputs: {\n props: createExtensionInput(\n [\n coreExtensionData.reactElement.optional(),\n titleExtensionDataRef.optional(),\n ],\n {\n singleton: true,\n optional: true,\n },\n ),\n },\n factory: (originalFactory, { inputs }) => {\n return originalFactory({\n defaultPath: '/home',\n routeRef: rootRouteRef,\n loader: () =>\n import('./components/').then(m =>\n compatWrapper(\n <m.HomepageCompositionRoot\n children={inputs.props?.get(coreExtensionData.reactElement)}\n title={inputs.props?.get(titleExtensionDataRef)}\n />,\n ),\n ),\n });\n },\n});\n\n/**\n * @alpha\n */\nexport default createFrontendPlugin({\n pluginId: 'home',\n extensions: [homePage],\n routes: {\n root: rootRouteRef,\n },\n});\n"],"names":[],"mappings":";;;;AA0BA,MAAM,eAAe,cAAe,EAAA;AAKvB,MAAA,qBAAA,GAAwB,sBAA+B,EAAA,CAAE,IAAK,CAAA;AAAA,EACzE,EAAI,EAAA;AACN,CAAC;AAED,MAAM,QAAA,GAAW,cAAc,iBAAkB,CAAA;AAAA,EAC/C,MAAQ,EAAA;AAAA,IACN,KAAO,EAAA,oBAAA;AAAA,MACL;AAAA,QACE,iBAAA,CAAkB,aAAa,QAAS,EAAA;AAAA,QACxC,sBAAsB,QAAS;AAAA,OACjC;AAAA,MACA;AAAA,QACE,SAAW,EAAA,IAAA;AAAA,QACX,QAAU,EAAA;AAAA;AACZ;AACF,GACF;AAAA,EACA,OAAS,EAAA,CAAC,eAAiB,EAAA,EAAE,QAAa,KAAA;AACxC,IAAA,OAAO,eAAgB,CAAA;AAAA,MACrB,WAAa,EAAA,OAAA;AAAA,MACb,QAAU,EAAA,YAAA;AAAA,MACV,MAAQ,EAAA,MACN,OAAO,2BAAe,CAAE,CAAA,IAAA;AAAA,QAAK,CAC3B,CAAA,KAAA,aAAA;AAAA,0BACE,GAAA;AAAA,YAAC,CAAE,CAAA,uBAAA;AAAA,YAAF;AAAA,cACC,QAAU,EAAA,MAAA,CAAO,KAAO,EAAA,GAAA,CAAI,kBAAkB,YAAY,CAAA;AAAA,cAC1D,KAAO,EAAA,MAAA,CAAO,KAAO,EAAA,GAAA,CAAI,qBAAqB;AAAA;AAAA;AAChD;AACF;AACF,KACH,CAAA;AAAA;AAEL,CAAC,CAAA;AAKD,YAAe,oBAAqB,CAAA;AAAA,EAClC,QAAU,EAAA,MAAA;AAAA,EACV,UAAA,EAAY,CAAC,QAAQ,CAAA;AAAA,EACrB,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA;AAAA;AAEV,CAAC,CAAA;;;;"}
@@ -242,7 +242,7 @@ const CustomHomepageGrid = (props) => {
242
242
  );
243
243
  };
244
244
  return /* @__PURE__ */ jsxs(Fragment, { children: [
245
- /* @__PURE__ */ jsx(ContentHeader, { title: "", children: /* @__PURE__ */ jsx(
245
+ /* @__PURE__ */ jsx(ContentHeader, { title: props.title, children: /* @__PURE__ */ jsx(
246
246
  CustomHomepageButtons,
247
247
  {
248
248
  editMode,
@@ -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 { isValidElement, useState, useCallback, useMemo } 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 { ContentHeader, ErrorBoundary } 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';\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] {\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 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];\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 [widgets, setWidgets] = useHomeStorage(defaultLayout);\n const [addWidgetDialogOpen, setAddWidgetDialogOpen] = useState(false);\n const editModeOn = widgets.find(w => w.layout.isResizable) !== undefined;\n const [editMode, setEditMode] = useState(editModeOn);\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\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([]);\n };\n\n const changeEditMode = (mode: boolean) => {\n setEditMode(mode);\n setWidgets(\n 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 };\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 return (\n <>\n <ContentHeader 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 />\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 No widgets added. Start by clicking the 'Add widget' button.\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 { isValidElement, useState, useCallback, useMemo } 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 { ContentHeader, ErrorBoundary } 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';\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] {\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 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];\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 [widgets, setWidgets] = useHomeStorage(defaultLayout);\n const [addWidgetDialogOpen, setAddWidgetDialogOpen] = useState(false);\n const editModeOn = widgets.find(w => w.layout.isResizable) !== undefined;\n const [editMode, setEditMode] = useState(editModeOn);\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\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([]);\n };\n\n const changeEditMode = (mode: boolean) => {\n setEditMode(mode);\n setWidgets(\n 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 };\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 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 />\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 No widgets added. Start by clicking the 'Add widget' button.\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';\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 * 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 false\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":"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"}
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';\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":"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"}
@@ -2,15 +2,27 @@ import { jsx } from 'react/jsx-runtime';
2
2
  import Typography from '@material-ui/core/Typography';
3
3
  import { makeStyles } from '@material-ui/core/styles';
4
4
  import { Link } from '@backstage/core-components';
5
+ import { EntityRefLink } from '@backstage/plugin-catalog-react';
5
6
 
6
- const useStyles = makeStyles((_theme) => ({
7
+ const useStyles = makeStyles((theme) => ({
7
8
  name: {
8
9
  marginLeft: "0.8rem",
9
- marginRight: "0.8rem"
10
+ marginRight: "0.8rem",
11
+ fontSize: theme.typography.body1.fontSize
10
12
  }
11
13
  }));
12
14
  const ItemName = ({ visit }) => {
13
15
  const classes = useStyles();
16
+ if (visit.entityRef)
17
+ return /* @__PURE__ */ jsx(
18
+ EntityRefLink,
19
+ {
20
+ entityRef: visit.entityRef,
21
+ className: classes.name,
22
+ hideIcon: true,
23
+ disableTooltip: true
24
+ }
25
+ );
14
26
  return /* @__PURE__ */ jsx(
15
27
  Typography,
16
28
  {
@@ -1 +1 @@
1
- {"version":3,"file":"ItemName.esm.js","sources":["../../../src/components/VisitList/ItemName.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 Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { Visit } from '../../api/VisitsApi';\nimport { Link } from '@backstage/core-components';\n\nconst useStyles = makeStyles(_theme => ({\n name: {\n marginLeft: '0.8rem',\n marginRight: '0.8rem',\n },\n}));\nexport const ItemName = ({ visit }: { visit: Visit }) => {\n const classes = useStyles();\n\n return (\n <Typography\n component={Link}\n to={visit.pathname}\n noWrap\n className={classes.name}\n >\n {visit.name}\n </Typography>\n );\n};\n"],"names":[],"mappings":";;;;;AAqBA,MAAM,SAAA,GAAY,WAAW,CAAW,MAAA,MAAA;AAAA,EACtC,IAAM,EAAA;AAAA,IACJ,UAAY,EAAA,QAAA;AAAA,IACZ,WAAa,EAAA;AAAA;AAEjB,CAAE,CAAA,CAAA;AACK,MAAM,QAAW,GAAA,CAAC,EAAE,KAAA,EAA8B,KAAA;AACvD,EAAA,MAAM,UAAU,SAAU,EAAA;AAE1B,EACE,uBAAA,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,SAAW,EAAA,IAAA;AAAA,MACX,IAAI,KAAM,CAAA,QAAA;AAAA,MACV,MAAM,EAAA,IAAA;AAAA,MACN,WAAW,OAAQ,CAAA,IAAA;AAAA,MAElB,QAAM,EAAA,KAAA,CAAA;AAAA;AAAA,GACT;AAEJ;;;;"}
1
+ {"version":3,"file":"ItemName.esm.js","sources":["../../../src/components/VisitList/ItemName.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 Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { Visit } from '../../api/VisitsApi';\nimport { Link } from '@backstage/core-components';\nimport { EntityRefLink } from '@backstage/plugin-catalog-react';\n\nconst useStyles = makeStyles(theme => ({\n name: {\n marginLeft: '0.8rem',\n marginRight: '0.8rem',\n fontSize: theme.typography.body1.fontSize,\n },\n}));\nexport const ItemName = ({ visit }: { visit: Visit }) => {\n const classes = useStyles();\n\n if (visit.entityRef)\n return (\n <EntityRefLink\n entityRef={visit.entityRef}\n className={classes.name}\n hideIcon\n disableTooltip\n />\n );\n\n return (\n <Typography\n component={Link}\n to={visit.pathname}\n noWrap\n className={classes.name}\n >\n {visit.name}\n </Typography>\n );\n};\n"],"names":[],"mappings":";;;;;;AAsBA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,IAAM,EAAA;AAAA,IACJ,UAAY,EAAA,QAAA;AAAA,IACZ,WAAa,EAAA,QAAA;AAAA,IACb,QAAA,EAAU,KAAM,CAAA,UAAA,CAAW,KAAM,CAAA;AAAA;AAErC,CAAE,CAAA,CAAA;AACK,MAAM,QAAW,GAAA,CAAC,EAAE,KAAA,EAA8B,KAAA;AACvD,EAAA,MAAM,UAAU,SAAU,EAAA;AAE1B,EAAA,IAAI,KAAM,CAAA,SAAA;AACR,IACE,uBAAA,GAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,WAAW,KAAM,CAAA,SAAA;AAAA,QACjB,WAAW,OAAQ,CAAA,IAAA;AAAA,QACnB,QAAQ,EAAA,IAAA;AAAA,QACR,cAAc,EAAA;AAAA;AAAA,KAChB;AAGJ,EACE,uBAAA,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,SAAW,EAAA,IAAA;AAAA,MACX,IAAI,KAAM,CAAA,QAAA;AAAA,MACV,MAAM,EAAA,IAAA;AAAA,MACN,WAAW,OAAQ,CAAA,IAAA;AAAA,MAElB,QAAM,EAAA,KAAA,CAAA;AAAA;AAAA,GACT;AAEJ;;;;"}
@@ -2,7 +2,7 @@ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
2
  import { Link } from '@backstage/core-components';
3
3
  import Typography from '@material-ui/core/Typography';
4
4
  import Grid from '@material-ui/core/Grid';
5
- import { ContentModal } from './ContentModal.esm.js';
5
+ import { ContentModal } from '@backstage/plugin-home-react';
6
6
  import { useStyles } from './styles.esm.js';
7
7
 
8
8
  const Content = (props) => {
@@ -39,7 +39,7 @@ const Content = (props) => {
39
39
  ]
40
40
  }
41
41
  ),
42
- props.video && props.video
42
+ props.additionalContent && props.additionalContent || props.video && props.video
43
43
  ] });
44
44
  };
45
45
 
@@ -1 +1 @@
1
- {"version":3,"file":"Content.esm.js","sources":["../../../src/homePageComponents/QuickStart/Content.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 { JSX } from 'react';\nimport { Link } from '@backstage/core-components';\nimport Typography from '@material-ui/core/Typography';\nimport Grid from '@material-ui/core/Grid';\nimport { ContentModal } from './ContentModal';\nimport { useStyles } from './styles';\n\n/**\n * Props customizing the <QuickStartCard/> component.\n *\n * @public\n */\nexport type QuickStartCardProps = {\n /** The modal link title */\n modalTitle?: string | JSX.Element;\n /** The link to docs title */\n docsLinkTitle?: string;\n /** The link to docs */\n docsLink?: string;\n /** The video to play on the card */\n video?: JSX.Element;\n /** A quickstart image to display on the card */\n image: JSX.Element;\n /** The card description*/\n cardDescription?: string;\n /** A component used to download a quickStart image*/\n downloadImage?: JSX.Element;\n};\n\n/**\n * A component to display Quick Start info on the homepage.\n *\n * @public\n */\nexport const Content = (props: QuickStartCardProps): JSX.Element => {\n const styles = useStyles();\n return (\n <>\n <ContentModal\n modalContent={props.image}\n linkContent={props.modalTitle || 'Onboarding'}\n />\n <Typography variant=\"body1\" paragraph>\n {props.cardDescription || 'Get started with Backstage'}\n </Typography>\n <ContentModal modalContent={props.image} linkContent={props.image} />\n <Grid\n container\n alignItems=\"center\"\n className={styles.contentActionContainer}\n >\n {props.downloadImage && <Grid item>{props.downloadImage}</Grid>}\n <Grid item>\n <Link\n to={props.docsLink || 'https://backstage.io/docs/getting-started/'}\n data-testid=\"quick-start-link-to-docs\"\n underline=\"none\"\n variant=\"h6\"\n className={styles.link}\n >\n {props.docsLinkTitle || 'Learn more'}\n </Link>\n </Grid>\n </Grid>\n {props.video && props.video}\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAkDa,MAAA,OAAA,GAAU,CAAC,KAA4C,KAAA;AAClE,EAAA,MAAM,SAAS,SAAU,EAAA;AACzB,EAAA,uBAEI,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACC,cAAc,KAAM,CAAA,KAAA;AAAA,QACpB,WAAA,EAAa,MAAM,UAAc,IAAA;AAAA;AAAA,KACnC;AAAA,oBACA,GAAA,CAAC,cAAW,OAAQ,EAAA,OAAA,EAAQ,WAAS,IAClC,EAAA,QAAA,EAAA,KAAA,CAAM,mBAAmB,4BAC5B,EAAA,CAAA;AAAA,wBACC,YAAa,EAAA,EAAA,YAAA,EAAc,MAAM,KAAO,EAAA,WAAA,EAAa,MAAM,KAAO,EAAA,CAAA;AAAA,oBACnE,IAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,SAAS,EAAA,IAAA;AAAA,QACT,UAAW,EAAA,QAAA;AAAA,QACX,WAAW,MAAO,CAAA,sBAAA;AAAA,QAEjB,QAAA,EAAA;AAAA,UAAA,KAAA,CAAM,iCAAkB,GAAA,CAAA,IAAA,EAAA,EAAK,IAAI,EAAA,IAAA,EAAE,gBAAM,aAAc,EAAA,CAAA;AAAA,0BACxD,GAAA,CAAC,IAAK,EAAA,EAAA,IAAA,EAAI,IACR,EAAA,QAAA,kBAAA,GAAA;AAAA,YAAC,IAAA;AAAA,YAAA;AAAA,cACC,EAAA,EAAI,MAAM,QAAY,IAAA,4CAAA;AAAA,cACtB,aAAY,EAAA,0BAAA;AAAA,cACZ,SAAU,EAAA,MAAA;AAAA,cACV,OAAQ,EAAA,IAAA;AAAA,cACR,WAAW,MAAO,CAAA,IAAA;AAAA,cAEjB,gBAAM,aAAiB,IAAA;AAAA;AAAA,WAE5B,EAAA;AAAA;AAAA;AAAA,KACF;AAAA,IACC,KAAA,CAAM,SAAS,KAAM,CAAA;AAAA,GACxB,EAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"Content.esm.js","sources":["../../../src/homePageComponents/QuickStart/Content.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 { JSX } from 'react';\nimport { Link } from '@backstage/core-components';\nimport Typography from '@material-ui/core/Typography';\nimport Grid from '@material-ui/core/Grid';\nimport { ContentModal } from '@backstage/plugin-home-react';\nimport { useStyles } from './styles';\n\n/**\n * Props customizing the <QuickStartCard/> component.\n *\n * @public\n */\nexport type QuickStartCardProps = {\n /** The modal link title */\n modalTitle?: string | JSX.Element;\n /** The link to docs title */\n docsLinkTitle?: string | JSX.Element;\n /** The link to docs */\n docsLink?: string;\n /** The video to play on the card\n * @deprecated This will be removed in the future, please use `additionalContent` instead\n */\n video?: JSX.Element;\n /** Additional card content */\n additionalContent?: JSX.Element;\n /** A quickstart image to display on the card */\n image: JSX.Element;\n /** The card description*/\n cardDescription?: string;\n /** A component used to download a quickStart image*/\n downloadImage?: JSX.Element;\n};\n\n/**\n * A component to display Quick Start info on the homepage.\n *\n * @public\n */\nexport const Content = (props: QuickStartCardProps): JSX.Element => {\n const styles = useStyles();\n return (\n <>\n <ContentModal\n modalContent={props.image}\n linkContent={props.modalTitle || 'Onboarding'}\n />\n <Typography variant=\"body1\" paragraph>\n {props.cardDescription || 'Get started with Backstage'}\n </Typography>\n <ContentModal modalContent={props.image} linkContent={props.image} />\n <Grid\n container\n alignItems=\"center\"\n className={styles.contentActionContainer}\n >\n {props.downloadImage && <Grid item>{props.downloadImage}</Grid>}\n <Grid item>\n <Link\n to={props.docsLink || 'https://backstage.io/docs/getting-started/'}\n data-testid=\"quick-start-link-to-docs\"\n underline=\"none\"\n variant=\"h6\"\n className={styles.link}\n >\n {props.docsLinkTitle || 'Learn more'}\n </Link>\n </Grid>\n </Grid>\n {(props.additionalContent && props.additionalContent) ||\n (props.video && props.video)}\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAsDa,MAAA,OAAA,GAAU,CAAC,KAA4C,KAAA;AAClE,EAAA,MAAM,SAAS,SAAU,EAAA;AACzB,EAAA,uBAEI,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACC,cAAc,KAAM,CAAA,KAAA;AAAA,QACpB,WAAA,EAAa,MAAM,UAAc,IAAA;AAAA;AAAA,KACnC;AAAA,oBACA,GAAA,CAAC,cAAW,OAAQ,EAAA,OAAA,EAAQ,WAAS,IAClC,EAAA,QAAA,EAAA,KAAA,CAAM,mBAAmB,4BAC5B,EAAA,CAAA;AAAA,wBACC,YAAa,EAAA,EAAA,YAAA,EAAc,MAAM,KAAO,EAAA,WAAA,EAAa,MAAM,KAAO,EAAA,CAAA;AAAA,oBACnE,IAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,SAAS,EAAA,IAAA;AAAA,QACT,UAAW,EAAA,QAAA;AAAA,QACX,WAAW,MAAO,CAAA,sBAAA;AAAA,QAEjB,QAAA,EAAA;AAAA,UAAA,KAAA,CAAM,iCAAkB,GAAA,CAAA,IAAA,EAAA,EAAK,IAAI,EAAA,IAAA,EAAE,gBAAM,aAAc,EAAA,CAAA;AAAA,0BACxD,GAAA,CAAC,IAAK,EAAA,EAAA,IAAA,EAAI,IACR,EAAA,QAAA,kBAAA,GAAA;AAAA,YAAC,IAAA;AAAA,YAAA;AAAA,cACC,EAAA,EAAI,MAAM,QAAY,IAAA,4CAAA;AAAA,cACtB,aAAY,EAAA,0BAAA;AAAA,cACZ,SAAU,EAAA,MAAA;AAAA,cACV,OAAQ,EAAA,IAAA;AAAA,cACR,WAAW,MAAO,CAAA,IAAA;AAAA,cAEjB,gBAAM,aAAiB,IAAA;AAAA;AAAA,WAE5B,EAAA;AAAA;AAAA;AAAA,KACF;AAAA,IACE,MAAM,iBAAqB,IAAA,KAAA,CAAM,iBAChC,IAAA,KAAA,CAAM,SAAS,KAAM,CAAA;AAAA,GAC1B,EAAA,CAAA;AAEJ;;;;"}
@@ -6,7 +6,10 @@ import { useMemo, useEffect } from 'react';
6
6
  import useAsync from 'react-use/esm/useAsync';
7
7
  import { getTimeBasedGreeting } from './timeUtil.esm.js';
8
8
 
9
- const WelcomeTitle = ({ language }) => {
9
+ const WelcomeTitle = ({
10
+ language,
11
+ variant
12
+ }) => {
10
13
  const identityApi = useApi(identityApiRef);
11
14
  const alertApi = useApi(alertApiRef);
12
15
  const greeting = useMemo(() => getTimeBasedGreeting(language), [language]);
@@ -21,7 +24,7 @@ const WelcomeTitle = ({ language }) => {
21
24
  });
22
25
  }
23
26
  }, [error, alertApi]);
24
- return /* @__PURE__ */ jsx(Tooltip, { title: greeting.language, children: /* @__PURE__ */ jsx(Typography, { component: "span", variant: "inherit", children: `${greeting.greeting}${profile?.displayName ? `, ${profile?.displayName}` : ""}!` }) });
27
+ return /* @__PURE__ */ jsx(Tooltip, { title: greeting.language, children: /* @__PURE__ */ jsx(Typography, { component: "span", variant, children: `${greeting.greeting}${profile?.displayName ? `, ${profile?.displayName}` : ""}!` }) });
25
28
  };
26
29
 
27
30
  export { WelcomeTitle };
@@ -1 +1 @@
1
- {"version":3,"file":"WelcomeTitle.esm.js","sources":["../../../src/homePageComponents/WelcomeTitle/WelcomeTitle.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 {\n alertApiRef,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport { useEffect, useMemo } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { getTimeBasedGreeting } from './timeUtil';\n\n/** @public */\nexport type WelcomeTitleLanguageProps = {\n language?: string[];\n};\n\nexport const WelcomeTitle = ({ language }: WelcomeTitleLanguageProps) => {\n const identityApi = useApi(identityApiRef);\n const alertApi = useApi(alertApiRef);\n const greeting = useMemo(() => getTimeBasedGreeting(language), [language]);\n\n const { value: profile, error } = useAsync(() =>\n identityApi.getProfileInfo(),\n );\n\n useEffect(() => {\n if (error) {\n alertApi.post({\n message: `Failed to load user identity: ${error}`,\n severity: 'error',\n });\n }\n }, [error, alertApi]);\n\n return (\n <Tooltip title={greeting.language}>\n <Typography component=\"span\" variant=\"inherit\">{`${greeting.greeting}${\n profile?.displayName ? `, ${profile?.displayName}` : ''\n }!`}</Typography>\n </Tooltip>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AA+BO,MAAM,YAAe,GAAA,CAAC,EAAE,QAAA,EAA0C,KAAA;AACvE,EAAM,MAAA,WAAA,GAAc,OAAO,cAAc,CAAA;AACzC,EAAM,MAAA,QAAA,GAAW,OAAO,WAAW,CAAA;AACnC,EAAM,MAAA,QAAA,GAAW,QAAQ,MAAM,oBAAA,CAAqB,QAAQ,CAAG,EAAA,CAAC,QAAQ,CAAC,CAAA;AAEzE,EAAA,MAAM,EAAE,KAAA,EAAO,OAAS,EAAA,KAAA,EAAU,GAAA,QAAA;AAAA,IAAS,MACzC,YAAY,cAAe;AAAA,GAC7B;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,KAAO,EAAA;AACT,MAAA,QAAA,CAAS,IAAK,CAAA;AAAA,QACZ,OAAA,EAAS,iCAAiC,KAAK,CAAA,CAAA;AAAA,QAC/C,QAAU,EAAA;AAAA,OACX,CAAA;AAAA;AACH,GACC,EAAA,CAAC,KAAO,EAAA,QAAQ,CAAC,CAAA;AAEpB,EACE,uBAAA,GAAA,CAAC,WAAQ,KAAO,EAAA,QAAA,CAAS,UACvB,QAAC,kBAAA,GAAA,CAAA,UAAA,EAAA,EAAW,SAAU,EAAA,MAAA,EAAO,OAAQ,EAAA,SAAA,EAAW,aAAG,QAAS,CAAA,QAAQ,CAClE,EAAA,OAAA,EAAS,WAAc,GAAA,CAAA,EAAA,EAAK,SAAS,WAAW,CAAA,CAAA,GAAK,EACvD,CAAA,CAAA,CAAA,EAAI,CACN,EAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"WelcomeTitle.esm.js","sources":["../../../src/homePageComponents/WelcomeTitle/WelcomeTitle.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 {\n alertApiRef,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport { useEffect, useMemo } from 'react';\nimport useAsync from 'react-use/esm/useAsync';\nimport { getTimeBasedGreeting } from './timeUtil';\nimport { Variant } from '@material-ui/core/styles/createTypography';\n\n/** @public */\nexport type WelcomeTitleLanguageProps = {\n language?: string[];\n variant?: Variant | 'inherit';\n};\n\nexport const WelcomeTitle = ({\n language,\n variant,\n}: WelcomeTitleLanguageProps) => {\n const identityApi = useApi(identityApiRef);\n const alertApi = useApi(alertApiRef);\n const greeting = useMemo(() => getTimeBasedGreeting(language), [language]);\n\n const { value: profile, error } = useAsync(() =>\n identityApi.getProfileInfo(),\n );\n\n useEffect(() => {\n if (error) {\n alertApi.post({\n message: `Failed to load user identity: ${error}`,\n severity: 'error',\n });\n }\n }, [error, alertApi]);\n\n return (\n <Tooltip title={greeting.language}>\n <Typography component=\"span\" variant={variant}>{`${greeting.greeting}${\n profile?.displayName ? `, ${profile?.displayName}` : ''\n }!`}</Typography>\n </Tooltip>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAiCO,MAAM,eAAe,CAAC;AAAA,EAC3B,QAAA;AAAA,EACA;AACF,CAAiC,KAAA;AAC/B,EAAM,MAAA,WAAA,GAAc,OAAO,cAAc,CAAA;AACzC,EAAM,MAAA,QAAA,GAAW,OAAO,WAAW,CAAA;AACnC,EAAM,MAAA,QAAA,GAAW,QAAQ,MAAM,oBAAA,CAAqB,QAAQ,CAAG,EAAA,CAAC,QAAQ,CAAC,CAAA;AAEzE,EAAA,MAAM,EAAE,KAAA,EAAO,OAAS,EAAA,KAAA,EAAU,GAAA,QAAA;AAAA,IAAS,MACzC,YAAY,cAAe;AAAA,GAC7B;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,KAAO,EAAA;AACT,MAAA,QAAA,CAAS,IAAK,CAAA;AAAA,QACZ,OAAA,EAAS,iCAAiC,KAAK,CAAA,CAAA;AAAA,QAC/C,QAAU,EAAA;AAAA,OACX,CAAA;AAAA;AACH,GACC,EAAA,CAAC,KAAO,EAAA,QAAQ,CAAC,CAAA;AAEpB,EACE,uBAAA,GAAA,CAAC,WAAQ,KAAO,EAAA,QAAA,CAAS,UACvB,QAAC,kBAAA,GAAA,CAAA,UAAA,EAAA,EAAW,SAAU,EAAA,MAAA,EAAO,OAAmB,EAAA,QAAA,EAAA,CAAA,EAAG,SAAS,QAAQ,CAAA,EAClE,SAAS,WAAc,GAAA,CAAA,EAAA,EAAK,SAAS,WAAW,CAAA,CAAA,GAAK,EACvD,CAAA,CAAA,CAAA,EAAI,CACN,EAAA,CAAA;AAEJ;;;;"}
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import { createCardExtension as createCardExtension$1, CardExtensionProps as Car
3
3
  import * as react from 'react';
4
4
  import { ReactNode, JSX as JSX$1, CSSProperties, ReactElement } from 'react';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
+ import { Variant } from '@material-ui/core/styles/createTypography';
6
7
  import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
7
8
  import { StorageApi, IdentityApi, ErrorApi } from '@backstage/core-plugin-api';
8
9
  import { EntityFilterQuery } from '@backstage/catalog-client';
@@ -32,6 +33,7 @@ type ClockConfig = {
32
33
  /** @public */
33
34
  type WelcomeTitleLanguageProps = {
34
35
  language?: string[];
36
+ variant?: Variant | 'inherit';
35
37
  };
36
38
 
37
39
  /**
@@ -236,11 +238,15 @@ type QuickStartCardProps = {
236
238
  /** The modal link title */
237
239
  modalTitle?: string | JSX$1.Element;
238
240
  /** The link to docs title */
239
- docsLinkTitle?: string;
241
+ docsLinkTitle?: string | JSX$1.Element;
240
242
  /** The link to docs */
241
243
  docsLink?: string;
242
- /** The video to play on the card */
244
+ /** The video to play on the card
245
+ * @deprecated This will be removed in the future, please use `additionalContent` instead
246
+ */
243
247
  video?: JSX$1.Element;
248
+ /** Additional card content */
249
+ additionalContent?: JSX$1.Element;
244
250
  /** A quickstart image to display on the card */
245
251
  image: JSX$1.Element;
246
252
  /** The card description*/
@@ -286,7 +292,7 @@ declare const ComponentTab: (props: {
286
292
  *
287
293
  * @public
288
294
  */
289
- declare const WelcomeTitle: ({ language }: WelcomeTitleLanguageProps) => react_jsx_runtime.JSX.Element;
295
+ declare const WelcomeTitle: ({ language, variant, }: WelcomeTitleLanguageProps) => react_jsx_runtime.JSX.Element;
290
296
  /**
291
297
  * A component to display a company logo for the user.
292
298
  *
@@ -364,6 +370,10 @@ type CustomHomepageGridProps = {
364
370
  * Default layout for the homepage before users have modified it.
365
371
  */
366
372
  config?: LayoutConfiguration[];
373
+ /**
374
+ * Title displayed in the header of the grid. If not provided, no title will be shown.
375
+ */
376
+ title?: string;
367
377
  /**
368
378
  * Height of grid row in pixels.
369
379
  * @defaultValue 60
@@ -414,7 +424,7 @@ type CustomHomepageGridProps = {
414
424
  allowOverlap?: boolean;
415
425
  /**
416
426
  * Controls if widgets can collide with each other. If true, grid items won't change position when being dragged over.
417
- * @defaultValue false
427
+ * @defaultValue true
418
428
  */
419
429
  preventCollision?: boolean;
420
430
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-home",
3
- "version": "0.8.8-next.2",
3
+ "version": "0.8.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.10.0-next.0",
72
- "@backstage/catalog-model": "1.7.3",
73
- "@backstage/config": "1.3.2",
74
- "@backstage/core-app-api": "1.16.2-next.0",
75
- "@backstage/core-compat-api": "0.4.2-next.2",
76
- "@backstage/core-components": "0.17.2-next.1",
77
- "@backstage/core-plugin-api": "1.10.7-next.0",
78
- "@backstage/frontend-plugin-api": "0.10.2-next.1",
79
- "@backstage/plugin-catalog-react": "1.18.0-next.2",
80
- "@backstage/plugin-home-react": "0.1.26-next.1",
81
- "@backstage/theme": "0.6.6-next.0",
71
+ "@backstage/catalog-client": "^1.10.0",
72
+ "@backstage/catalog-model": "^1.7.4",
73
+ "@backstage/config": "^1.3.2",
74
+ "@backstage/core-app-api": "^1.17.0",
75
+ "@backstage/core-compat-api": "^0.4.2",
76
+ "@backstage/core-components": "^0.17.2",
77
+ "@backstage/core-plugin-api": "^1.10.7",
78
+ "@backstage/frontend-plugin-api": "^0.10.2",
79
+ "@backstage/plugin-catalog-react": "^1.18.0",
80
+ "@backstage/plugin-home-react": "^0.1.26",
81
+ "@backstage/theme": "^0.6.6",
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,9 +94,9 @@
94
94
  "zod": "^3.22.4"
95
95
  },
96
96
  "devDependencies": {
97
- "@backstage/cli": "0.32.1-next.2",
98
- "@backstage/dev-utils": "1.1.10-next.2",
99
- "@backstage/test-utils": "1.7.8-next.1",
97
+ "@backstage/cli": "^0.32.1",
98
+ "@backstage/dev-utils": "^1.1.10",
99
+ "@backstage/test-utils": "^1.7.8",
100
100
  "@testing-library/dom": "^10.0.0",
101
101
  "@testing-library/jest-dom": "^6.0.0",
102
102
  "@testing-library/react": "^16.0.0",
@@ -1,38 +0,0 @@
1
- import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { useState } from 'react';
3
- import { Link } from '@backstage/core-components';
4
- import Modal from '@material-ui/core/Modal';
5
- import Box from '@material-ui/core/Box';
6
- import { useStyles } from './styles.esm.js';
7
-
8
- const ContentModal = (props) => {
9
- const { modalContent, linkContent } = props;
10
- const styles = useStyles();
11
- const [open, setOpen] = useState(false);
12
- return /* @__PURE__ */ jsxs("div", { className: styles.linkText, "data-testid": "content-modal-container", children: [
13
- /* @__PURE__ */ jsx(
14
- Link,
15
- {
16
- to: "#",
17
- component: "button",
18
- variant: "h6",
19
- underline: "none",
20
- onClick: () => setOpen(true),
21
- children: linkContent
22
- }
23
- ),
24
- /* @__PURE__ */ jsx(
25
- Modal,
26
- {
27
- open,
28
- onClose: () => setOpen(false),
29
- "aria-labelledby": "content-modal",
30
- "data-testid": "content-modal",
31
- children: /* @__PURE__ */ jsx(Box, { className: styles.contentModal, "data-testid": "content-modal-open", children: modalContent })
32
- }
33
- )
34
- ] });
35
- };
36
-
37
- export { ContentModal };
38
- //# sourceMappingURL=ContentModal.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ContentModal.esm.js","sources":["../../../src/homePageComponents/QuickStart/ContentModal.tsx"],"sourcesContent":["/*\n * Copyright 2022 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 { JSX, useState } from 'react';\nimport { Link } from '@backstage/core-components';\nimport Modal from '@material-ui/core/Modal';\nimport Box from '@material-ui/core/Box';\n\nimport { useStyles } from './styles';\n\nexport type ContentModalProps = {\n modalContent: JSX.Element;\n linkContent: string | JSX.Element;\n};\n\nexport const ContentModal = (props: ContentModalProps) => {\n const { modalContent, linkContent } = props;\n const styles = useStyles();\n const [open, setOpen] = useState(false);\n\n return (\n <div className={styles.linkText} data-testid=\"content-modal-container\">\n <Link\n to=\"#\"\n component=\"button\"\n variant=\"h6\"\n underline=\"none\"\n onClick={() => setOpen(true)}\n >\n {linkContent}\n </Link>\n <Modal\n open={open}\n onClose={() => setOpen(false)}\n aria-labelledby=\"content-modal\"\n data-testid=\"content-modal\"\n >\n <Box className={styles.contentModal} data-testid=\"content-modal-open\">\n {modalContent}\n </Box>\n </Modal>\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;;AA4Ba,MAAA,YAAA,GAAe,CAAC,KAA6B,KAAA;AACxD,EAAM,MAAA,EAAE,YAAc,EAAA,WAAA,EAAgB,GAAA,KAAA;AACtC,EAAA,MAAM,SAAS,SAAU,EAAA;AACzB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,KAAK,CAAA;AAEtC,EAAA,4BACG,KAAI,EAAA,EAAA,SAAA,EAAW,MAAO,CAAA,QAAA,EAAU,eAAY,yBAC3C,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,EAAG,EAAA,GAAA;AAAA,QACH,SAAU,EAAA,QAAA;AAAA,QACV,OAAQ,EAAA,IAAA;AAAA,QACR,SAAU,EAAA,MAAA;AAAA,QACV,OAAA,EAAS,MAAM,OAAA,CAAQ,IAAI,CAAA;AAAA,QAE1B,QAAA,EAAA;AAAA;AAAA,KACH;AAAA,oBACA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,OAAA,EAAS,MAAM,OAAA,CAAQ,KAAK,CAAA;AAAA,QAC5B,iBAAgB,EAAA,eAAA;AAAA,QAChB,aAAY,EAAA,eAAA;AAAA,QAEZ,8BAAC,GAAI,EAAA,EAAA,SAAA,EAAW,OAAO,YAAc,EAAA,aAAA,EAAY,sBAC9C,QACH,EAAA,YAAA,EAAA;AAAA;AAAA;AACF,GACF,EAAA,CAAA;AAEJ;;;;"}