@backstage/plugin-home 0.8.16-next.1 → 0.9.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @backstage/plugin-home
2
2
 
3
+ ## 0.9.0-next.2
4
+
5
+ ### Minor Changes
6
+
7
+ - e091a83: Widget configurations are now only saved to storage when the Save button is explicitly clicked. Added a Cancel button that allows users to discard unsaved changes and revert to the last saved state.
8
+
3
9
  ## 0.8.16-next.1
4
10
 
5
11
  ### Patch Changes
package/dist/alpha.d.ts CHANGED
@@ -7,6 +7,7 @@ import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api'
7
7
  declare const homeTranslationRef: _backstage_frontend_plugin_api.TranslationRef<"home", {
8
8
  readonly "starredEntities.noStarredEntitiesMessage": "Click the star beside an entity name to add it to this list!";
9
9
  readonly "addWidgetDialog.title": "Add new widget to dashboard";
10
+ readonly "customHomepageButtons.cancel": "Cancel";
10
11
  readonly "customHomepageButtons.clearAll": "Clear all";
11
12
  readonly "customHomepageButtons.edit": "Edit";
12
13
  readonly "customHomepageButtons.restoreDefaults": "Restore defaults";
@@ -30,7 +30,8 @@ const CustomHomepageButtons = (props) => {
30
30
  setAddWidgetDialogOpen,
31
31
  changeEditMode,
32
32
  defaultConfigAvailable,
33
- restoreDefault
33
+ restoreDefault,
34
+ cancel
34
35
  } = props;
35
36
  const styles = useStyles();
36
37
  const { t } = useTranslationRef(homeTranslationRef);
@@ -45,6 +46,7 @@ const CustomHomepageButtons = (props) => {
45
46
  children: t("customHomepageButtons.edit")
46
47
  }
47
48
  ) : /* @__PURE__ */ jsxs(Fragment, { children: [
49
+ /* @__PURE__ */ jsx(Button, { variant: "contained", onClick: cancel, size: "small", children: t("customHomepageButtons.cancel") }),
48
50
  defaultConfigAvailable && /* @__PURE__ */ jsx(
49
51
  Button,
50
52
  {
@@ -1 +1 @@
1
- {"version":3,"file":"CustomHomepageButtons.esm.js","sources":["../../../src/components/CustomHomepage/CustomHomepageButtons.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 */\nimport Button from '@material-ui/core/Button';\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\nimport SaveIcon from '@material-ui/icons/Save';\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport AddIcon from '@material-ui/icons/Add';\nimport EditIcon from '@material-ui/icons/Edit';\nimport CancelIcon from '@material-ui/icons/Cancel';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport { homeTranslationRef } from '../../translation';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n contentHeaderBtn: {\n marginLeft: theme.spacing(2),\n },\n widgetWrapper: {\n '& > *:first-child': {\n width: '100%',\n height: '100%',\n },\n },\n }),\n);\n\ninterface CustomHomepageButtonsProps {\n editMode: boolean;\n numWidgets: number;\n clearLayout: () => void;\n setAddWidgetDialogOpen: (open: boolean) => void;\n changeEditMode: (mode: boolean) => void;\n defaultConfigAvailable: boolean;\n restoreDefault: () => void;\n}\nexport const CustomHomepageButtons = (props: CustomHomepageButtonsProps) => {\n const {\n editMode,\n numWidgets,\n clearLayout,\n setAddWidgetDialogOpen,\n changeEditMode,\n defaultConfigAvailable,\n restoreDefault,\n } = props;\n const styles = useStyles();\n const { t } = useTranslationRef(homeTranslationRef);\n\n return (\n <>\n {!editMode && numWidgets > 0 ? (\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={() => changeEditMode(true)}\n size=\"small\"\n startIcon={<EditIcon />}\n >\n {t('customHomepageButtons.edit')}\n </Button>\n ) : (\n <>\n {defaultConfigAvailable && (\n <Button\n variant=\"contained\"\n className={styles.contentHeaderBtn}\n onClick={restoreDefault}\n size=\"small\"\n startIcon={<CancelIcon />}\n >\n {t('customHomepageButtons.restoreDefaults')}\n </Button>\n )}\n {numWidgets > 0 && (\n <Button\n variant=\"contained\"\n color=\"secondary\"\n className={styles.contentHeaderBtn}\n onClick={clearLayout}\n size=\"small\"\n startIcon={<DeleteIcon />}\n >\n {t('customHomepageButtons.clearAll')}\n </Button>\n )}\n <Button\n variant=\"contained\"\n className={styles.contentHeaderBtn}\n onClick={() => setAddWidgetDialogOpen(true)}\n size=\"small\"\n startIcon={<AddIcon />}\n >\n {t('customHomepageButtons.addWidget')}\n </Button>\n {numWidgets > 0 && (\n <Button\n className={styles.contentHeaderBtn}\n variant=\"contained\"\n color=\"primary\"\n onClick={() => changeEditMode(false)}\n size=\"small\"\n startIcon={<SaveIcon />}\n >\n {t('customHomepageButtons.save')}\n </Button>\n )}\n </>\n )}\n </>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;AAyBA,MAAM,SAAA,GAAY,UAAA;AAAA,EAAW,CAAC,UAC5B,YAAA,CAAa;AAAA,IACX,gBAAA,EAAkB;AAAA,MAChB,UAAA,EAAY,KAAA,CAAM,OAAA,CAAQ,CAAC;AAAA,KAC7B;AAAA,IACA,aAAA,EAAe;AAAA,MACb,mBAAA,EAAqB;AAAA,QACnB,KAAA,EAAO,MAAA;AAAA,QACP,MAAA,EAAQ;AAAA;AACV;AACF,GACD;AACH,CAAA;AAWO,MAAM,qBAAA,GAAwB,CAAC,KAAA,KAAsC;AAC1E,EAAA,MAAM;AAAA,IACJ,QAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA;AAAA,IACA,sBAAA;AAAA,IACA,cAAA;AAAA,IACA,sBAAA;AAAA,IACA;AAAA,GACF,GAAI,KAAA;AACJ,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,kBAAkB,CAAA;AAElD,EAAA,uBACE,GAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA,CAAC,QAAA,IAAY,UAAA,GAAa,CAAA,mBACzB,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAQ,WAAA;AAAA,MACR,KAAA,EAAM,SAAA;AAAA,MACN,OAAA,EAAS,MAAM,cAAA,CAAe,IAAI,CAAA;AAAA,MAClC,IAAA,EAAK,OAAA;AAAA,MACL,SAAA,sBAAY,QAAA,EAAA,EAAS,CAAA;AAAA,MAEpB,YAAE,4BAA4B;AAAA;AAAA,sBAGjC,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,sBAAA,oBACC,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,WAAA;AAAA,QACR,WAAW,MAAA,CAAO,gBAAA;AAAA,QAClB,OAAA,EAAS,cAAA;AAAA,QACT,IAAA,EAAK,OAAA;AAAA,QACL,SAAA,sBAAY,UAAA,EAAA,EAAW,CAAA;AAAA,QAEtB,YAAE,uCAAuC;AAAA;AAAA,KAC5C;AAAA,IAED,aAAa,CAAA,oBACZ,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,WAAA;AAAA,QACR,KAAA,EAAM,WAAA;AAAA,QACN,WAAW,MAAA,CAAO,gBAAA;AAAA,QAClB,OAAA,EAAS,WAAA;AAAA,QACT,IAAA,EAAK,OAAA;AAAA,QACL,SAAA,sBAAY,UAAA,EAAA,EAAW,CAAA;AAAA,QAEtB,YAAE,gCAAgC;AAAA;AAAA,KACrC;AAAA,oBAEF,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,WAAA;AAAA,QACR,WAAW,MAAA,CAAO,gBAAA;AAAA,QAClB,OAAA,EAAS,MAAM,sBAAA,CAAuB,IAAI,CAAA;AAAA,QAC1C,IAAA,EAAK,OAAA;AAAA,QACL,SAAA,sBAAY,OAAA,EAAA,EAAQ,CAAA;AAAA,QAEnB,YAAE,iCAAiC;AAAA;AAAA,KACtC;AAAA,IACC,aAAa,CAAA,oBACZ,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,WAAW,MAAA,CAAO,gBAAA;AAAA,QAClB,OAAA,EAAQ,WAAA;AAAA,QACR,KAAA,EAAM,SAAA;AAAA,QACN,OAAA,EAAS,MAAM,cAAA,CAAe,KAAK,CAAA;AAAA,QACnC,IAAA,EAAK,OAAA;AAAA,QACL,SAAA,sBAAY,QAAA,EAAA,EAAS,CAAA;AAAA,QAEpB,YAAE,4BAA4B;AAAA;AAAA;AACjC,GAAA,EAEJ,CAAA,EAEJ,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"CustomHomepageButtons.esm.js","sources":["../../../src/components/CustomHomepage/CustomHomepageButtons.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 */\nimport Button from '@material-ui/core/Button';\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\nimport SaveIcon from '@material-ui/icons/Save';\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport AddIcon from '@material-ui/icons/Add';\nimport EditIcon from '@material-ui/icons/Edit';\nimport CancelIcon from '@material-ui/icons/Cancel';\nimport { useTranslationRef } from '@backstage/frontend-plugin-api';\nimport { homeTranslationRef } from '../../translation';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n contentHeaderBtn: {\n marginLeft: theme.spacing(2),\n },\n widgetWrapper: {\n '& > *:first-child': {\n width: '100%',\n height: '100%',\n },\n },\n }),\n);\n\ninterface CustomHomepageButtonsProps {\n editMode: boolean;\n numWidgets: number;\n clearLayout: () => void;\n setAddWidgetDialogOpen: (open: boolean) => void;\n changeEditMode: (mode: boolean) => void;\n defaultConfigAvailable: boolean;\n restoreDefault: () => void;\n cancel: () => void;\n}\nexport const CustomHomepageButtons = (props: CustomHomepageButtonsProps) => {\n const {\n editMode,\n numWidgets,\n clearLayout,\n setAddWidgetDialogOpen,\n changeEditMode,\n defaultConfigAvailable,\n restoreDefault,\n cancel,\n } = props;\n const styles = useStyles();\n const { t } = useTranslationRef(homeTranslationRef);\n\n return (\n <>\n {!editMode && numWidgets > 0 ? (\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={() => changeEditMode(true)}\n size=\"small\"\n startIcon={<EditIcon />}\n >\n {t('customHomepageButtons.edit')}\n </Button>\n ) : (\n <>\n <Button variant=\"contained\" onClick={cancel} size=\"small\">\n {t('customHomepageButtons.cancel')}\n </Button>\n {defaultConfigAvailable && (\n <Button\n variant=\"contained\"\n className={styles.contentHeaderBtn}\n onClick={restoreDefault}\n size=\"small\"\n startIcon={<CancelIcon />}\n >\n {t('customHomepageButtons.restoreDefaults')}\n </Button>\n )}\n {numWidgets > 0 && (\n <Button\n variant=\"contained\"\n color=\"secondary\"\n className={styles.contentHeaderBtn}\n onClick={clearLayout}\n size=\"small\"\n startIcon={<DeleteIcon />}\n >\n {t('customHomepageButtons.clearAll')}\n </Button>\n )}\n <Button\n variant=\"contained\"\n className={styles.contentHeaderBtn}\n onClick={() => setAddWidgetDialogOpen(true)}\n size=\"small\"\n startIcon={<AddIcon />}\n >\n {t('customHomepageButtons.addWidget')}\n </Button>\n {numWidgets > 0 && (\n <Button\n className={styles.contentHeaderBtn}\n variant=\"contained\"\n color=\"primary\"\n onClick={() => changeEditMode(false)}\n size=\"small\"\n startIcon={<SaveIcon />}\n >\n {t('customHomepageButtons.save')}\n </Button>\n )}\n </>\n )}\n </>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { useMemo, useState, isValidElement, useCallback } from 'react';
2
+ import { useMemo, useState, useEffect, isValidElement, useCallback } from 'react';
3
3
  import { WidthProvider, Responsive } from 'react-grid-layout';
4
4
  import { useElementFilter, getComponentData, useApi, storageApiRef } from '@backstage/core-plugin-api';
5
5
  import 'react-grid-layout/css/styles.css';
@@ -151,10 +151,14 @@ const CustomHomepageGrid = (props) => {
151
151
  const defaultLayout = useMemo(() => {
152
152
  return props.config ? convertConfigToDefaultWidgets(props.config, availableWidgets) : [];
153
153
  }, [props.config, availableWidgets]);
154
- const [widgets, setWidgets, isStorageLoading] = useHomeStorage(defaultLayout);
154
+ const [storedWidgets, storeWidgets, isStorageLoading] = useHomeStorage(defaultLayout);
155
+ const [widgets, setWidgets] = useState(storedWidgets);
155
156
  const [addWidgetDialogOpen, setAddWidgetDialogOpen] = useState(false);
156
157
  const editModeOn = widgets.find((w) => w.layout.isResizable) !== void 0;
157
158
  const [editMode, setEditMode] = useState(editModeOn);
159
+ useEffect(() => {
160
+ setWidgets(storedWidgets);
161
+ }, [storedWidgets]);
158
162
  const getWidgetByName = (name) => {
159
163
  return availableWidgets.find((widget) => widget.name === name);
160
164
  };
@@ -206,16 +210,17 @@ const CustomHomepageGrid = (props) => {
206
210
  };
207
211
  const changeEditMode = (mode) => {
208
212
  setEditMode(mode);
209
- setWidgets(
210
- widgets.map((w) => {
213
+ if (!mode) {
214
+ const newWidgets = widgets.map((w) => {
211
215
  const resizable = w.resizable === false ? false : mode;
212
216
  const movable = w.movable === false ? false : mode;
213
217
  return {
214
218
  ...w,
215
219
  layout: { ...w.layout, isDraggable: movable, isResizable: resizable }
216
220
  };
217
- })
218
- );
221
+ });
222
+ storeWidgets(newWidgets);
223
+ }
219
224
  };
220
225
  const handleLayoutChange = (newLayout, _) => {
221
226
  if (editMode) {
@@ -245,6 +250,10 @@ const CustomHomepageGrid = (props) => {
245
250
  })
246
251
  );
247
252
  };
253
+ const handleCancel = () => {
254
+ setWidgets(storedWidgets);
255
+ setEditMode(false);
256
+ };
248
257
  if (isStorageLoading) {
249
258
  return /* @__PURE__ */ jsx(Progress, {});
250
259
  }
@@ -258,7 +267,8 @@ const CustomHomepageGrid = (props) => {
258
267
  setAddWidgetDialogOpen,
259
268
  changeEditMode,
260
269
  defaultConfigAvailable: props.config !== void 0,
261
- restoreDefault: handleRestoreDefaultConfig
270
+ restoreDefault: handleRestoreDefaultConfig,
271
+ cancel: handleCancel
262
272
  }
263
273
  ) }),
264
274
  /* @__PURE__ */ jsx(
@@ -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 {\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 [widgets, setWidgets, isStorageLoading] = 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 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 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 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 />\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 [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 if (!mode) {\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 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,5 +1,5 @@
1
1
  var name = "@backstage/plugin-home";
2
- var version = "0.8.16-next.1";
2
+ var version = "0.9.0-next.2";
3
3
  var description = "A Backstage plugin that helps you build a home page";
4
4
  var backstage = {
5
5
  role: "frontend-plugin",
@@ -11,7 +11,8 @@ const homeTranslationRef = createTranslationRef({
11
11
  restoreDefaults: "Restore defaults",
12
12
  clearAll: "Clear all",
13
13
  addWidget: "Add widget",
14
- save: "Save"
14
+ save: "Save",
15
+ cancel: "Cancel"
15
16
  },
16
17
  customHomepage: {
17
18
  noWidgets: "No widgets added. Start by clicking the 'Add widget' button."
@@ -1 +1 @@
1
- {"version":3,"file":"translation.esm.js","sources":["../src/translation.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { createTranslationRef } from '@backstage/frontend-plugin-api';\n\n/**\n * @alpha\n */\nexport const homeTranslationRef = createTranslationRef({\n id: 'home',\n messages: {\n addWidgetDialog: {\n title: 'Add new widget to dashboard',\n },\n customHomepageButtons: {\n edit: 'Edit',\n restoreDefaults: 'Restore defaults',\n clearAll: 'Clear all',\n addWidget: 'Add widget',\n save: 'Save',\n },\n customHomepage: {\n noWidgets: \"No widgets added. Start by clicking the 'Add widget' button.\",\n },\n widgetSettingsOverlay: {\n editSettingsTooptip: 'Edit settings',\n deleteWidgetTooltip: 'Delete widget',\n submitButtonTitle: 'Submit',\n cancelButtonTitle: 'Cancel',\n },\n starredEntityListItem: {\n removeFavoriteEntityTitle: 'Remove entity from favorites',\n },\n visitList: {\n empty: {\n title: 'There are no visits to show yet.',\n description:\n 'Once you start using Backstage, your visits will appear here as a quick link to carry on where you left off.',\n },\n few: {\n title: 'The more pages you visit, the more pages will appear here.',\n },\n },\n quickStart: {\n title: 'Onboarding',\n description: 'Get started with Backstage',\n learnMoreLinkTitle: 'Learn more',\n },\n starredEntities: {\n noStarredEntitiesMessage:\n 'Click the star beside an entity name to add it to this list!',\n },\n visitedByType: {\n action: {\n viewMore: 'View more',\n viewLess: 'View less',\n },\n },\n featuredDocsCard: {\n learnMoreTitle: 'LEARN MORE',\n empty: {\n title: 'No documents to show',\n description:\n 'Create your own document. Check out our Getting Started Information',\n learnMoreLinkTitle: 'DOCS',\n },\n },\n },\n});\n"],"names":[],"mappings":";;AAoBO,MAAM,qBAAqB,oBAAA,CAAqB;AAAA,EACrD,EAAA,EAAI,MAAA;AAAA,EACJ,QAAA,EAAU;AAAA,IACR,eAAA,EAAiB;AAAA,MACf,KAAA,EAAO;AAAA,KACT;AAAA,IACA,qBAAA,EAAuB;AAAA,MACrB,IAAA,EAAM,MAAA;AAAA,MACN,eAAA,EAAiB,kBAAA;AAAA,MACjB,QAAA,EAAU,WAAA;AAAA,MACV,SAAA,EAAW,YAAA;AAAA,MACX,IAAA,EAAM;AAAA,KACR;AAAA,IACA,cAAA,EAAgB;AAAA,MACd,SAAA,EAAW;AAAA,KACb;AAAA,IACA,qBAAA,EAAuB;AAAA,MACrB,mBAAA,EAAqB,eAAA;AAAA,MACrB,mBAAA,EAAqB,eAAA;AAAA,MACrB,iBAAA,EAAmB,QAAA;AAAA,MACnB,iBAAA,EAAmB;AAAA,KACrB;AAAA,IACA,qBAAA,EAAuB;AAAA,MACrB,yBAAA,EAA2B;AAAA,KAC7B;AAAA,IACA,SAAA,EAAW;AAAA,MACT,KAAA,EAAO;AAAA,QACL,KAAA,EAAO,kCAAA;AAAA,QACP,WAAA,EACE;AAAA,OACJ;AAAA,MACA,GAAA,EAAK;AAAA,QACH,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,UAAA,EAAY;AAAA,MACV,KAAA,EAAO,YAAA;AAAA,MACP,WAAA,EAAa,4BAAA;AAAA,MACb,kBAAA,EAAoB;AAAA,KACtB;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,wBAAA,EACE;AAAA,KACJ;AAAA,IACA,aAAA,EAAe;AAAA,MACb,MAAA,EAAQ;AAAA,QACN,QAAA,EAAU,WAAA;AAAA,QACV,QAAA,EAAU;AAAA;AACZ,KACF;AAAA,IACA,gBAAA,EAAkB;AAAA,MAChB,cAAA,EAAgB,YAAA;AAAA,MAChB,KAAA,EAAO;AAAA,QACL,KAAA,EAAO,sBAAA;AAAA,QACP,WAAA,EACE,qEAAA;AAAA,QACF,kBAAA,EAAoB;AAAA;AACtB;AACF;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"translation.esm.js","sources":["../src/translation.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { createTranslationRef } from '@backstage/frontend-plugin-api';\n\n/**\n * @alpha\n */\nexport const homeTranslationRef = createTranslationRef({\n id: 'home',\n messages: {\n addWidgetDialog: {\n title: 'Add new widget to dashboard',\n },\n customHomepageButtons: {\n edit: 'Edit',\n restoreDefaults: 'Restore defaults',\n clearAll: 'Clear all',\n addWidget: 'Add widget',\n save: 'Save',\n cancel: 'Cancel',\n },\n customHomepage: {\n noWidgets: \"No widgets added. Start by clicking the 'Add widget' button.\",\n },\n widgetSettingsOverlay: {\n editSettingsTooptip: 'Edit settings',\n deleteWidgetTooltip: 'Delete widget',\n submitButtonTitle: 'Submit',\n cancelButtonTitle: 'Cancel',\n },\n starredEntityListItem: {\n removeFavoriteEntityTitle: 'Remove entity from favorites',\n },\n visitList: {\n empty: {\n title: 'There are no visits to show yet.',\n description:\n 'Once you start using Backstage, your visits will appear here as a quick link to carry on where you left off.',\n },\n few: {\n title: 'The more pages you visit, the more pages will appear here.',\n },\n },\n quickStart: {\n title: 'Onboarding',\n description: 'Get started with Backstage',\n learnMoreLinkTitle: 'Learn more',\n },\n starredEntities: {\n noStarredEntitiesMessage:\n 'Click the star beside an entity name to add it to this list!',\n },\n visitedByType: {\n action: {\n viewMore: 'View more',\n viewLess: 'View less',\n },\n },\n featuredDocsCard: {\n learnMoreTitle: 'LEARN MORE',\n empty: {\n title: 'No documents to show',\n description:\n 'Create your own document. Check out our Getting Started Information',\n learnMoreLinkTitle: 'DOCS',\n },\n },\n },\n});\n"],"names":[],"mappings":";;AAoBO,MAAM,qBAAqB,oBAAA,CAAqB;AAAA,EACrD,EAAA,EAAI,MAAA;AAAA,EACJ,QAAA,EAAU;AAAA,IACR,eAAA,EAAiB;AAAA,MACf,KAAA,EAAO;AAAA,KACT;AAAA,IACA,qBAAA,EAAuB;AAAA,MACrB,IAAA,EAAM,MAAA;AAAA,MACN,eAAA,EAAiB,kBAAA;AAAA,MACjB,QAAA,EAAU,WAAA;AAAA,MACV,SAAA,EAAW,YAAA;AAAA,MACX,IAAA,EAAM,MAAA;AAAA,MACN,MAAA,EAAQ;AAAA,KACV;AAAA,IACA,cAAA,EAAgB;AAAA,MACd,SAAA,EAAW;AAAA,KACb;AAAA,IACA,qBAAA,EAAuB;AAAA,MACrB,mBAAA,EAAqB,eAAA;AAAA,MACrB,mBAAA,EAAqB,eAAA;AAAA,MACrB,iBAAA,EAAmB,QAAA;AAAA,MACnB,iBAAA,EAAmB;AAAA,KACrB;AAAA,IACA,qBAAA,EAAuB;AAAA,MACrB,yBAAA,EAA2B;AAAA,KAC7B;AAAA,IACA,SAAA,EAAW;AAAA,MACT,KAAA,EAAO;AAAA,QACL,KAAA,EAAO,kCAAA;AAAA,QACP,WAAA,EACE;AAAA,OACJ;AAAA,MACA,GAAA,EAAK;AAAA,QACH,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,UAAA,EAAY;AAAA,MACV,KAAA,EAAO,YAAA;AAAA,MACP,WAAA,EAAa,4BAAA;AAAA,MACb,kBAAA,EAAoB;AAAA,KACtB;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,wBAAA,EACE;AAAA,KACJ;AAAA,IACA,aAAA,EAAe;AAAA,MACb,MAAA,EAAQ;AAAA,QACN,QAAA,EAAU,WAAA;AAAA,QACV,QAAA,EAAU;AAAA;AACZ,KACF;AAAA,IACA,gBAAA,EAAkB;AAAA,MAChB,cAAA,EAAgB,YAAA;AAAA,MAChB,KAAA,EAAO;AAAA,QACL,KAAA,EAAO,sBAAA;AAAA,QACP,WAAA,EACE,qEAAA;AAAA,QACF,kBAAA,EAAoB;AAAA;AACtB;AACF;AAEJ,CAAC;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-home",
3
- "version": "0.8.16-next.1",
3
+ "version": "0.9.0-next.2",
4
4
  "description": "A Backstage plugin that helps you build a home page",
5
5
  "backstage": {
6
6
  "role": "frontend-plugin",