@red-hat-developer-hub/backstage-plugin-dynamic-home-page 1.11.0 → 1.13.0

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/alpha/components/CustomizableGridLayout.esm.js +17 -7
  3. package/dist/alpha/components/CustomizableGridLayout.esm.js.map +1 -1
  4. package/dist/alpha/extensions/apis.esm.js +15 -2
  5. package/dist/alpha/extensions/apis.esm.js.map +1 -1
  6. package/dist/alpha/extensions/homePageCards.esm.js +6 -6
  7. package/dist/alpha/extensions/homePageCards.esm.js.map +1 -1
  8. package/dist/alpha.d.ts +1 -1
  9. package/dist/alpha.esm.js +2 -1
  10. package/dist/alpha.esm.js.map +1 -1
  11. package/dist/api/DefaultWidgetsApiClient.esm.js +26 -0
  12. package/dist/api/DefaultWidgetsApiClient.esm.js.map +1 -0
  13. package/dist/components/CustomizableGrid.esm.js +17 -7
  14. package/dist/components/CustomizableGrid.esm.js.map +1 -1
  15. package/dist/components/DefaultWidgetsCustomizableGrid.esm.js +138 -0
  16. package/dist/components/DefaultWidgetsCustomizableGrid.esm.js.map +1 -0
  17. package/dist/components/DefaultWidgetsReadOnlyGrid.esm.js +146 -0
  18. package/dist/components/DefaultWidgetsReadOnlyGrid.esm.js.map +1 -0
  19. package/dist/components/EntitySection/EntitySection.esm.js +1 -8
  20. package/dist/components/EntitySection/EntitySection.esm.js.map +1 -1
  21. package/dist/components/HomePage.esm.js +27 -3
  22. package/dist/components/HomePage.esm.js.map +1 -1
  23. package/dist/hooks/useContainerQuery.esm.js +40 -5
  24. package/dist/hooks/useContainerQuery.esm.js.map +1 -1
  25. package/dist/hooks/useDefaultWidgets.esm.js +19 -0
  26. package/dist/hooks/useDefaultWidgets.esm.js.map +1 -0
  27. package/dist/index.d.ts +24 -11
  28. package/dist/index.esm.js +1 -0
  29. package/dist/index.esm.js.map +1 -1
  30. package/dist/plugin.esm.js +11 -2
  31. package/dist/plugin.esm.js.map +1 -1
  32. package/dist/translations/de.esm.js +1 -1
  33. package/dist/translations/de.esm.js.map +1 -1
  34. package/dist/translations/es.esm.js +1 -1
  35. package/dist/translations/es.esm.js.map +1 -1
  36. package/dist/translations/fr.esm.js +1 -1
  37. package/dist/translations/fr.esm.js.map +1 -1
  38. package/dist/translations/it.esm.js +1 -1
  39. package/dist/translations/it.esm.js.map +1 -1
  40. package/dist/translations/ja.esm.js +1 -1
  41. package/dist/translations/ja.esm.js.map +1 -1
  42. package/dist/translations/ref.esm.js +1 -1
  43. package/dist/translations/ref.esm.js.map +1 -1
  44. package/dist/utils/customizable-cards.esm.js.map +1 -1
  45. package/package.json +27 -23
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @red-hat-developer-hub/backstage-plugin-dynamic-home-page
2
2
 
3
+ ## 1.13.0
4
+
5
+ ### Minor Changes
6
+
7
+ - a5a1846: Homepage default content is now resolved through a new backend with RBAC, widget-oriented configuration, and translated titles. Bumps `@red-hat-developer-hub/backstage-plugin-theme` to `^0.14.1`.
8
+
9
+ **`@red-hat-developer-hub/backstage-plugin-dynamic-home-page`**
10
+
11
+ - Load default widgets from the homepage backend API (permission-aware), with a frontend API client and hooks.
12
+
13
+ **`@red-hat-developer-hub/backstage-plugin-homepage-backend` and `@red-hat-developer-hub/backstage-plugin-homepage-common`**
14
+
15
+ - Initial release: backend resolves default widgets using user context, `if` conditions; shared types and permission definitions live in homepage-common.
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [a5a1846]
20
+ - @red-hat-developer-hub/backstage-plugin-homepage-common@0.1.0
21
+
22
+ ## 1.12.0
23
+
24
+ ### Minor Changes
25
+
26
+ - e8780ce: Backstage version bump to v1.49.3
27
+
28
+ ### Patch Changes
29
+
30
+ - 7ea283a: fixes the responsiveness issue of the customizable home-page
31
+ - 4e40bf1: Fix misleading entity count in EntitySection card link
32
+
3
33
  ## 1.11.0
4
34
 
5
35
  ### Minor Changes
@@ -1,8 +1,9 @@
1
1
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
- import { useMemo, Fragment as Fragment$1 } from 'react';
2
+ import { useRef, useMemo, Fragment as Fragment$1 } from 'react';
3
3
  import { CustomHomepageGrid } from '@backstage/plugin-home';
4
4
  import { useTheme } from '@mui/material/styles';
5
5
  import GlobalStyles from '@mui/material/GlobalStyles';
6
+ import { useContainerQuery } from '../../hooks/useContainerQuery.esm.js';
6
7
  import 'react-grid-layout/css/styles.css';
7
8
  import { isCardADefaultConfiguration } from '../utils.esm.js';
8
9
 
@@ -10,6 +11,8 @@ const CustomizableGridLayout = ({
10
11
  homepageCards
11
12
  }) => {
12
13
  const theme = useTheme();
14
+ const gridContainerRef = useRef(null);
15
+ useContainerQuery(gridContainerRef, { notifyWindowResize: true });
13
16
  const config = useMemo(() => {
14
17
  const defaultConfig = [];
15
18
  homepageCards.forEach((homepageCard) => {
@@ -44,13 +47,20 @@ const CustomizableGridLayout = ({
44
47
  }
45
48
  ),
46
49
  /* @__PURE__ */ jsx(
47
- CustomHomepageGrid,
50
+ "div",
48
51
  {
49
- config,
50
- preventCollision: false,
51
- compactType: "vertical",
52
- style: { margin: "-10px" },
53
- children: homepageCards.map((card, index) => /* @__PURE__ */ jsx(Fragment$1, { children: card.component }, card.name ?? index))
52
+ ref: gridContainerRef,
53
+ style: { width: "100%", minWidth: 0, boxSizing: "border-box" },
54
+ children: /* @__PURE__ */ jsx(
55
+ CustomHomepageGrid,
56
+ {
57
+ config,
58
+ preventCollision: false,
59
+ compactType: "vertical",
60
+ style: { margin: "-10px" },
61
+ children: homepageCards.map((card, index) => /* @__PURE__ */ jsx(Fragment$1, { children: card.component }, card.name ?? index))
62
+ }
63
+ )
54
64
  }
55
65
  )
56
66
  ] });
@@ -1 +1 @@
1
- {"version":3,"file":"CustomizableGridLayout.esm.js","sources":["../../../src/alpha/components/CustomizableGridLayout.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// This complete read-only home page grid picks up the idea and styles from\n// https://github.com/backstage/backstage/blob/master/plugins/home\n// Esp. from the CustomHomepageGrid component:\n// https://github.com/backstage/backstage/blob/master/plugins/home/src/components/CustomHomepage/CustomHomepageGrid.tsx\n// but without the drag and drop functionality.\n\nimport { Fragment, useMemo } from 'react';\n\nimport {\n CustomHomepageGrid,\n LayoutConfiguration,\n} from '@backstage/plugin-home';\nimport { useTheme } from '@mui/material/styles';\nimport GlobalStyles from '@mui/material/GlobalStyles';\nimport { HomePageCardConfig } from '../../types';\n\nimport 'react-grid-layout/css/styles.css';\nimport { isCardADefaultConfiguration } from '../utils';\n\n/**\n * Props for the customizable grid layout.\n * @alpha\n */\nexport interface CustomizableGridLayoutProps {\n homepageCards: HomePageCardConfig[];\n}\n\n/**\n * Customizable grid layout for the NFS home page (drag, drop, resize).\n *\n * @alpha\n */\nexport const CustomizableGridLayout = ({\n homepageCards,\n}: CustomizableGridLayoutProps) => {\n const theme = useTheme();\n\n const config = useMemo(() => {\n const defaultConfig: LayoutConfiguration[] = [];\n\n homepageCards.forEach(homepageCard => {\n if (!homepageCard.node) {\n return;\n }\n\n if (isCardADefaultConfiguration(homepageCard)) {\n const layout = homepageCard.breakpointLayouts?.xl || {};\n\n defaultConfig.push({\n component: homepageCard.component,\n x: layout.x ?? 0,\n y: layout.y ?? 0,\n width: layout.w ?? 12,\n height: layout.h ?? 4,\n movable: true,\n deletable: true,\n resizable: true,\n });\n }\n });\n\n return defaultConfig;\n }, [homepageCards]);\n\n return (\n <>\n <GlobalStyles\n styles={{\n '[class*=\"makeStyles-settingsOverlay\"]': {\n backgroundColor:\n theme.palette.mode === 'dark'\n ? 'rgba(20, 20, 20, 0.95) !important'\n : 'rgba(40, 40, 40, 0.93) !important',\n },\n }}\n />\n <CustomHomepageGrid\n config={config}\n preventCollision={false}\n compactType=\"vertical\"\n style={{ margin: '-10px' }}\n >\n {homepageCards.map((card, index) => (\n <Fragment key={card.name ?? index}>{card.component}</Fragment>\n ))}\n </CustomHomepageGrid>\n </>\n );\n};\n"],"names":["Fragment"],"mappings":";;;;;;;;AAgDO,MAAM,yBAAyB,CAAC;AAAA,EACrC;AACF,CAAmC,KAAA;AACjC,EAAA,MAAM,QAAQ,QAAS,EAAA;AAEvB,EAAM,MAAA,MAAA,GAAS,QAAQ,MAAM;AAC3B,IAAA,MAAM,gBAAuC,EAAC;AAE9C,IAAA,aAAA,CAAc,QAAQ,CAAgB,YAAA,KAAA;AACpC,MAAI,IAAA,CAAC,aAAa,IAAM,EAAA;AACtB,QAAA;AAAA;AAGF,MAAI,IAAA,2BAAA,CAA4B,YAAY,CAAG,EAAA;AAC7C,QAAA,MAAM,MAAS,GAAA,YAAA,CAAa,iBAAmB,EAAA,EAAA,IAAM,EAAC;AAEtD,QAAA,aAAA,CAAc,IAAK,CAAA;AAAA,UACjB,WAAW,YAAa,CAAA,SAAA;AAAA,UACxB,CAAA,EAAG,OAAO,CAAK,IAAA,CAAA;AAAA,UACf,CAAA,EAAG,OAAO,CAAK,IAAA,CAAA;AAAA,UACf,KAAA,EAAO,OAAO,CAAK,IAAA,EAAA;AAAA,UACnB,MAAA,EAAQ,OAAO,CAAK,IAAA,CAAA;AAAA,UACpB,OAAS,EAAA,IAAA;AAAA,UACT,SAAW,EAAA,IAAA;AAAA,UACX,SAAW,EAAA;AAAA,SACZ,CAAA;AAAA;AACH,KACD,CAAA;AAED,IAAO,OAAA,aAAA;AAAA,GACT,EAAG,CAAC,aAAa,CAAC,CAAA;AAElB,EAAA,uBAEI,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACC,MAAQ,EAAA;AAAA,UACN,uCAAyC,EAAA;AAAA,YACvC,eACE,EAAA,KAAA,CAAM,OAAQ,CAAA,IAAA,KAAS,SACnB,mCACA,GAAA;AAAA;AACR;AACF;AAAA,KACF;AAAA,oBACA,GAAA;AAAA,MAAC,kBAAA;AAAA,MAAA;AAAA,QACC,MAAA;AAAA,QACA,gBAAkB,EAAA,KAAA;AAAA,QAClB,WAAY,EAAA,UAAA;AAAA,QACZ,KAAA,EAAO,EAAE,MAAA,EAAQ,OAAQ,EAAA;AAAA,QAExB,QAAc,EAAA,aAAA,CAAA,GAAA,CAAI,CAAC,IAAA,EAAM,KACxB,qBAAA,GAAA,CAACA,UAAA,EAAA,EAAmC,QAAK,EAAA,IAAA,CAAA,SAAA,EAAA,EAA1B,IAAK,CAAA,IAAA,IAAQ,KAAuB,CACpD;AAAA;AAAA;AACH,GACF,EAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"CustomizableGridLayout.esm.js","sources":["../../../src/alpha/components/CustomizableGridLayout.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// This complete read-only home page grid picks up the idea and styles from\n// https://github.com/backstage/backstage/blob/master/plugins/home\n// Esp. from the CustomHomepageGrid component:\n// https://github.com/backstage/backstage/blob/master/plugins/home/src/components/CustomHomepage/CustomHomepageGrid.tsx\n// but without the drag and drop functionality.\n\nimport { Fragment, useMemo, useRef } from 'react';\n\nimport {\n CustomHomepageGrid,\n LayoutConfiguration,\n} from '@backstage/plugin-home';\nimport { useTheme } from '@mui/material/styles';\nimport GlobalStyles from '@mui/material/GlobalStyles';\nimport { HomePageCardConfig } from '../../types';\nimport { useContainerQuery } from '../../hooks/useContainerQuery';\n\nimport 'react-grid-layout/css/styles.css';\nimport { isCardADefaultConfiguration } from '../utils';\n\n/**\n * Props for the customizable grid layout.\n * @alpha\n */\nexport interface CustomizableGridLayoutProps {\n homepageCards: HomePageCardConfig[];\n}\n\n/**\n * Customizable grid layout for the NFS home page (drag, drop, resize).\n *\n * @alpha\n */\nexport const CustomizableGridLayout = ({\n homepageCards,\n}: CustomizableGridLayoutProps) => {\n const theme = useTheme();\n const gridContainerRef = useRef<HTMLDivElement>(null);\n useContainerQuery(gridContainerRef, { notifyWindowResize: true });\n\n const config = useMemo(() => {\n const defaultConfig: LayoutConfiguration[] = [];\n\n homepageCards.forEach(homepageCard => {\n if (!homepageCard.node) {\n return;\n }\n\n if (isCardADefaultConfiguration(homepageCard)) {\n const layout = homepageCard.breakpointLayouts?.xl || {};\n\n defaultConfig.push({\n component: homepageCard.component,\n x: layout.x ?? 0,\n y: layout.y ?? 0,\n width: layout.w ?? 12,\n height: layout.h ?? 4,\n movable: true,\n deletable: true,\n resizable: true,\n });\n }\n });\n\n return defaultConfig;\n }, [homepageCards]);\n\n return (\n <>\n <GlobalStyles\n styles={{\n '[class*=\"makeStyles-settingsOverlay\"]': {\n backgroundColor:\n theme.palette.mode === 'dark'\n ? 'rgba(20, 20, 20, 0.95) !important'\n : 'rgba(40, 40, 40, 0.93) !important',\n },\n }}\n />\n <div\n ref={gridContainerRef}\n style={{ width: '100%', minWidth: 0, boxSizing: 'border-box' }}\n >\n <CustomHomepageGrid\n config={config}\n preventCollision={false}\n compactType=\"vertical\"\n style={{ margin: '-10px' }}\n >\n {homepageCards.map((card, index) => (\n <Fragment key={card.name ?? index}>{card.component}</Fragment>\n ))}\n </CustomHomepageGrid>\n </div>\n </>\n );\n};\n"],"names":["Fragment"],"mappings":";;;;;;;;;AAiDO,MAAM,yBAAyB,CAAC;AAAA,EACrC;AACF,CAAmC,KAAA;AACjC,EAAA,MAAM,QAAQ,QAAS,EAAA;AACvB,EAAM,MAAA,gBAAA,GAAmB,OAAuB,IAAI,CAAA;AACpD,EAAA,iBAAA,CAAkB,gBAAkB,EAAA,EAAE,kBAAoB,EAAA,IAAA,EAAM,CAAA;AAEhE,EAAM,MAAA,MAAA,GAAS,QAAQ,MAAM;AAC3B,IAAA,MAAM,gBAAuC,EAAC;AAE9C,IAAA,aAAA,CAAc,QAAQ,CAAgB,YAAA,KAAA;AACpC,MAAI,IAAA,CAAC,aAAa,IAAM,EAAA;AACtB,QAAA;AAAA;AAGF,MAAI,IAAA,2BAAA,CAA4B,YAAY,CAAG,EAAA;AAC7C,QAAA,MAAM,MAAS,GAAA,YAAA,CAAa,iBAAmB,EAAA,EAAA,IAAM,EAAC;AAEtD,QAAA,aAAA,CAAc,IAAK,CAAA;AAAA,UACjB,WAAW,YAAa,CAAA,SAAA;AAAA,UACxB,CAAA,EAAG,OAAO,CAAK,IAAA,CAAA;AAAA,UACf,CAAA,EAAG,OAAO,CAAK,IAAA,CAAA;AAAA,UACf,KAAA,EAAO,OAAO,CAAK,IAAA,EAAA;AAAA,UACnB,MAAA,EAAQ,OAAO,CAAK,IAAA,CAAA;AAAA,UACpB,OAAS,EAAA,IAAA;AAAA,UACT,SAAW,EAAA,IAAA;AAAA,UACX,SAAW,EAAA;AAAA,SACZ,CAAA;AAAA;AACH,KACD,CAAA;AAED,IAAO,OAAA,aAAA;AAAA,GACT,EAAG,CAAC,aAAa,CAAC,CAAA;AAElB,EAAA,uBAEI,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACC,MAAQ,EAAA;AAAA,UACN,uCAAyC,EAAA;AAAA,YACvC,eACE,EAAA,KAAA,CAAM,OAAQ,CAAA,IAAA,KAAS,SACnB,mCACA,GAAA;AAAA;AACR;AACF;AAAA,KACF;AAAA,oBACA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAK,EAAA,gBAAA;AAAA,QACL,OAAO,EAAE,KAAA,EAAO,QAAQ,QAAU,EAAA,CAAA,EAAG,WAAW,YAAa,EAAA;AAAA,QAE7D,QAAA,kBAAA,GAAA;AAAA,UAAC,kBAAA;AAAA,UAAA;AAAA,YACC,MAAA;AAAA,YACA,gBAAkB,EAAA,KAAA;AAAA,YAClB,WAAY,EAAA,UAAA;AAAA,YACZ,KAAA,EAAO,EAAE,MAAA,EAAQ,OAAQ,EAAA;AAAA,YAExB,QAAc,EAAA,aAAA,CAAA,GAAA,CAAI,CAAC,IAAA,EAAM,KACxB,qBAAA,GAAA,CAACA,UAAA,EAAA,EAAmC,QAAK,EAAA,IAAA,CAAA,SAAA,EAAA,EAA1B,IAAK,CAAA,IAAA,IAAQ,KAAuB,CACpD;AAAA;AAAA;AACH;AAAA;AACF,GACF,EAAA,CAAA;AAEJ;;;;"}
@@ -1,4 +1,5 @@
1
- import { ApiBlueprint, discoveryApiRef, configApiRef, identityApiRef } from '@backstage/frontend-plugin-api';
1
+ import { ApiBlueprint, discoveryApiRef, configApiRef, identityApiRef, fetchApiRef } from '@backstage/frontend-plugin-api';
2
+ import { defaultWidgetsApiRef, DefaultWidgetsApiClient } from '../../api/DefaultWidgetsApiClient.esm.js';
2
3
  import { quickAccessApiRef, QuickAccessApiClient } from '../../api/QuickAccessApiClient.esm.js';
3
4
 
4
5
  const quickAccessApi = ApiBlueprint.make({
@@ -14,6 +15,18 @@ const quickAccessApi = ApiBlueprint.make({
14
15
  factory: ({ discoveryApi, configApi, identityApi }) => new QuickAccessApiClient({ discoveryApi, configApi, identityApi })
15
16
  })
16
17
  });
18
+ const defaultWidgetsApi = ApiBlueprint.make({
19
+ name: "default-widgets",
20
+ disabled: false,
21
+ params: (defineParams) => defineParams({
22
+ api: defaultWidgetsApiRef,
23
+ deps: {
24
+ discoveryApi: discoveryApiRef,
25
+ fetchApi: fetchApiRef
26
+ },
27
+ factory: ({ discoveryApi, fetchApi }) => new DefaultWidgetsApiClient({ discoveryApi, fetchApi })
28
+ })
29
+ });
17
30
 
18
- export { quickAccessApi };
31
+ export { defaultWidgetsApi, quickAccessApi };
19
32
  //# sourceMappingURL=apis.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"apis.esm.js","sources":["../../../src/alpha/extensions/apis.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 ApiBlueprint,\n configApiRef,\n discoveryApiRef,\n identityApiRef,\n} from '@backstage/frontend-plugin-api';\nimport { QuickAccessApiClient, quickAccessApiRef } from '../../api';\n\n/**\n * Quick access API for the New Frontend System.\n * Provides access to quick access links from app config.\n *\n * @alpha\n */\nconst quickAccessApi = ApiBlueprint.make({\n name: 'quickaccess',\n disabled: false,\n params: defineParams =>\n defineParams({\n api: quickAccessApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n configApi: configApiRef,\n identityApi: identityApiRef,\n },\n factory: ({ discoveryApi, configApi, identityApi }) =>\n new QuickAccessApiClient({ discoveryApi, configApi, identityApi }),\n }),\n});\n\nexport { quickAccessApi };\n"],"names":[],"mappings":";;;AA8BM,MAAA,cAAA,GAAiB,aAAa,IAAK,CAAA;AAAA,EACvC,IAAM,EAAA,aAAA;AAAA,EACN,QAAU,EAAA,KAAA;AAAA,EACV,MAAA,EAAQ,kBACN,YAAa,CAAA;AAAA,IACX,GAAK,EAAA,iBAAA;AAAA,IACL,IAAM,EAAA;AAAA,MACJ,YAAc,EAAA,eAAA;AAAA,MACd,SAAW,EAAA,YAAA;AAAA,MACX,WAAa,EAAA;AAAA,KACf;AAAA,IACA,OAAS,EAAA,CAAC,EAAE,YAAA,EAAc,SAAW,EAAA,WAAA,EACnC,KAAA,IAAI,oBAAqB,CAAA,EAAE,YAAc,EAAA,SAAA,EAAW,aAAa;AAAA,GACpE;AACL,CAAC;;;;"}
1
+ {"version":3,"file":"apis.esm.js","sources":["../../../src/alpha/extensions/apis.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 ApiBlueprint,\n configApiRef,\n discoveryApiRef,\n fetchApiRef,\n identityApiRef,\n} from '@backstage/frontend-plugin-api';\nimport {\n DefaultWidgetsApiClient,\n defaultWidgetsApiRef,\n QuickAccessApiClient,\n quickAccessApiRef,\n} from '../../api';\n\n/**\n * Quick access API for the New Frontend System.\n * Provides access to quick access links from app config.\n *\n * @alpha\n */\nconst quickAccessApi = ApiBlueprint.make({\n name: 'quickaccess',\n disabled: false,\n params: defineParams =>\n defineParams({\n api: quickAccessApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n configApi: configApiRef,\n identityApi: identityApiRef,\n },\n factory: ({ discoveryApi, configApi, identityApi }) =>\n new QuickAccessApiClient({ discoveryApi, configApi, identityApi }),\n }),\n});\n\n/**\n * Default cards API for the New Frontend System.\n * Provides access to permission-filtered homepage cards from the backend.\n *\n * @alpha\n */\nconst defaultWidgetsApi = ApiBlueprint.make({\n name: 'default-widgets',\n disabled: false,\n params: defineParams =>\n defineParams({\n api: defaultWidgetsApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ discoveryApi, fetchApi }) =>\n new DefaultWidgetsApiClient({ discoveryApi, fetchApi }),\n }),\n});\n\nexport { defaultWidgetsApi, quickAccessApi };\n"],"names":[],"mappings":";;;;AAoCM,MAAA,cAAA,GAAiB,aAAa,IAAK,CAAA;AAAA,EACvC,IAAM,EAAA,aAAA;AAAA,EACN,QAAU,EAAA,KAAA;AAAA,EACV,MAAA,EAAQ,kBACN,YAAa,CAAA;AAAA,IACX,GAAK,EAAA,iBAAA;AAAA,IACL,IAAM,EAAA;AAAA,MACJ,YAAc,EAAA,eAAA;AAAA,MACd,SAAW,EAAA,YAAA;AAAA,MACX,WAAa,EAAA;AAAA,KACf;AAAA,IACA,OAAS,EAAA,CAAC,EAAE,YAAA,EAAc,SAAW,EAAA,WAAA,EACnC,KAAA,IAAI,oBAAqB,CAAA,EAAE,YAAc,EAAA,SAAA,EAAW,aAAa;AAAA,GACpE;AACL,CAAC;AAQK,MAAA,iBAAA,GAAoB,aAAa,IAAK,CAAA;AAAA,EAC1C,IAAM,EAAA,iBAAA;AAAA,EACN,QAAU,EAAA,KAAA;AAAA,EACV,MAAA,EAAQ,kBACN,YAAa,CAAA;AAAA,IACX,GAAK,EAAA,oBAAA;AAAA,IACL,IAAM,EAAA;AAAA,MACJ,YAAc,EAAA,eAAA;AAAA,MACd,QAAU,EAAA;AAAA,KACZ;AAAA,IACA,OAAA,EAAS,CAAC,EAAE,YAAc,EAAA,QAAA,EACxB,KAAA,IAAI,uBAAwB,CAAA,EAAE,YAAc,EAAA,QAAA,EAAU;AAAA,GACzD;AACL,CAAC;;;;"}
@@ -18,7 +18,7 @@ const defaultCardLayout = {
18
18
  const onboardingSectionWidget = HomePageWidgetBlueprint.make({
19
19
  name: "rhdh-onboarding-section",
20
20
  params: {
21
- name: "RhdhOnboardingSection",
21
+ name: "Red Hat Developer Hub - Onboarding",
22
22
  layout: defaultCardLayout,
23
23
  components: () => import('../../components/OnboardingSection/index.esm.js').then((m) => ({
24
24
  Content: m.OnboardingSection
@@ -28,7 +28,7 @@ const onboardingSectionWidget = HomePageWidgetBlueprint.make({
28
28
  const entitySectionWidget = HomePageWidgetBlueprint.make({
29
29
  name: "rhdh-entity-section",
30
30
  params: {
31
- name: "RhdhEntitySection",
31
+ name: "Red Hat Developer Hub - Software Catalog",
32
32
  layout: defaultCardLayout,
33
33
  components: () => import('../../components/EntitySection/index.esm.js').then((m) => ({
34
34
  Content: () => compatWrapper(/* @__PURE__ */ jsx(m.EntitySection, {}))
@@ -38,7 +38,7 @@ const entitySectionWidget = HomePageWidgetBlueprint.make({
38
38
  const templateSectionWidget = HomePageWidgetBlueprint.make({
39
39
  name: "rhdh-template-section",
40
40
  params: {
41
- name: "RhdhTemplateSection",
41
+ name: "Red Hat Developer Hub - Explore templates",
42
42
  layout: defaultCardLayout,
43
43
  components: () => import('../../components/TemplateSection/index.esm.js').then((m) => ({
44
44
  Content: m.TemplateSection
@@ -48,7 +48,7 @@ const templateSectionWidget = HomePageWidgetBlueprint.make({
48
48
  const quickAccessCardWidget = HomePageWidgetBlueprint.make({
49
49
  name: "quick-access-card",
50
50
  params: {
51
- name: "QuickAccessCard",
51
+ name: "Quick Access Card",
52
52
  layout: defaultCardLayout,
53
53
  components: () => import('../../components/QuickAccessCard.esm.js').then((m) => ({
54
54
  Content: () => compatWrapper(/* @__PURE__ */ jsx(m.QuickAccessCard, {}))
@@ -58,7 +58,7 @@ const quickAccessCardWidget = HomePageWidgetBlueprint.make({
58
58
  const searchBarWidget = HomePageWidgetBlueprint.make({
59
59
  name: "search-bar",
60
60
  params: {
61
- name: "SearchBar",
61
+ name: "Search",
62
62
  layout: {
63
63
  ...defaultCardLayout,
64
64
  height: {
@@ -76,7 +76,7 @@ const searchBarWidget = HomePageWidgetBlueprint.make({
76
76
  const featuredDocsCardWidget = HomePageWidgetBlueprint.make({
77
77
  name: "featured-docs-card",
78
78
  params: {
79
- name: "FeaturedDocsCard",
79
+ name: "Featured docs",
80
80
  layout: defaultCardLayout,
81
81
  components: () => import('../../components/FeaturedDocsCard.esm.js').then((m) => ({
82
82
  Content: m.FeaturedDocsCard
@@ -1 +1 @@
1
- {"version":3,"file":"homePageCards.esm.js","sources":["../../../src/alpha/extensions/homePageCards.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 { HomePageWidgetBlueprint } from '@backstage/plugin-home-react/alpha';\nimport homePlugin from '@backstage/plugin-home/alpha';\nimport { compatWrapper } from '@backstage/core-compat-api';\n\nconst defaultCardLayout = {\n width: {\n minColumns: 4,\n maxColumns: 12,\n defaultColumns: 12,\n },\n height: {\n minRows: 2,\n maxRows: 12,\n defaultRows: 4,\n },\n} as const;\n\n/**\n * NFS widget: OnboardingSection (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const onboardingSectionWidget = HomePageWidgetBlueprint.make({\n name: 'rhdh-onboarding-section',\n params: {\n name: 'RhdhOnboardingSection',\n layout: defaultCardLayout,\n components: () =>\n import('../../components/OnboardingSection').then(m => ({\n Content: m.OnboardingSection,\n })),\n },\n});\n\n/**\n * NFS widget: EntitySection (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const entitySectionWidget = HomePageWidgetBlueprint.make({\n name: 'rhdh-entity-section',\n params: {\n name: 'RhdhEntitySection',\n layout: defaultCardLayout,\n components: () =>\n import('../../components/EntitySection').then(m => ({\n Content: () => compatWrapper(<m.EntitySection />),\n })),\n },\n});\n\n/**\n * NFS widget: TemplateSection (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const templateSectionWidget = HomePageWidgetBlueprint.make({\n name: 'rhdh-template-section',\n params: {\n name: 'RhdhTemplateSection',\n layout: defaultCardLayout,\n components: () =>\n import('../../components/TemplateSection').then(m => ({\n Content: m.TemplateSection,\n })),\n },\n});\n\n/**\n * NFS widget: QuickAccessCard (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const quickAccessCardWidget = HomePageWidgetBlueprint.make({\n name: 'quick-access-card',\n params: {\n name: 'QuickAccessCard',\n layout: defaultCardLayout,\n components: () =>\n import('../../components/QuickAccessCard').then(m => ({\n Content: () => compatWrapper(<m.QuickAccessCard />),\n })),\n },\n});\n\n/**\n * NFS widget: SearchBar (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const searchBarWidget = HomePageWidgetBlueprint.make({\n name: 'search-bar',\n params: {\n name: 'SearchBar',\n layout: {\n ...defaultCardLayout,\n height: {\n ...defaultCardLayout.height,\n defaultRows: 2,\n minRows: 1,\n maxRows: 1,\n },\n },\n components: () =>\n import('../../components/SearchBar').then(m => ({\n Content: () => compatWrapper(<m.SearchBar />),\n })),\n },\n});\n\n/**\n * NFS widget: FeaturedDocsCard (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const featuredDocsCardWidget = HomePageWidgetBlueprint.make({\n name: 'featured-docs-card',\n params: {\n name: 'FeaturedDocsCard',\n layout: defaultCardLayout,\n components: () =>\n import('../../components/FeaturedDocsCard').then(m => ({\n Content: m.FeaturedDocsCard,\n })),\n },\n});\n\n/**\n * NFS widget: CatalogStarred (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const catalogStarredWidget = homePlugin\n .getExtension('home-page-widget:home/starred-entities')\n .override({\n params: {\n name: 'CatalogStarred',\n title: 'Starred catalog entities',\n },\n });\n\n/**\n * Disables the default home plugin toolkit widget.\n * @alpha\n */\nexport const disableToolkit = homePlugin\n .getExtension('home-page-widget:home/toolkit')\n .override({\n disabled: true,\n });\n\n/**\n * NFS widget: RecentlyVisited (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const RecentlyVisitedWidget = HomePageWidgetBlueprint.make({\n name: 'recently-visited',\n params: {\n layout: defaultCardLayout,\n name: 'Recently visited',\n components: () =>\n import('@backstage/plugin-home').then(m => ({\n Content: m.HomePageRecentlyVisited,\n })),\n },\n});\n\n/**\n * NFS widget: TopVisited (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const TopVisitedWidget = HomePageWidgetBlueprint.make({\n name: 'top-visited',\n params: {\n layout: defaultCardLayout,\n name: 'Top visited',\n components: () =>\n import('@backstage/plugin-home').then(m => ({\n Content: () => <m.HomePageTopVisited />,\n })),\n },\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"homePageCards.esm.js","sources":["../../../src/alpha/extensions/homePageCards.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 { HomePageWidgetBlueprint } from '@backstage/plugin-home-react/alpha';\nimport homePlugin from '@backstage/plugin-home/alpha';\nimport { compatWrapper } from '@backstage/core-compat-api';\n\nconst defaultCardLayout = {\n width: {\n minColumns: 4,\n maxColumns: 12,\n defaultColumns: 12,\n },\n height: {\n minRows: 2,\n maxRows: 12,\n defaultRows: 4,\n },\n} as const;\n\n/**\n * NFS widget: OnboardingSection (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const onboardingSectionWidget = HomePageWidgetBlueprint.make({\n name: 'rhdh-onboarding-section',\n params: {\n name: 'Red Hat Developer Hub - Onboarding',\n layout: defaultCardLayout,\n components: () =>\n import('../../components/OnboardingSection').then(m => ({\n Content: m.OnboardingSection,\n })),\n },\n});\n\n/**\n * NFS widget: EntitySection (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const entitySectionWidget = HomePageWidgetBlueprint.make({\n name: 'rhdh-entity-section',\n params: {\n name: 'Red Hat Developer Hub - Software Catalog',\n layout: defaultCardLayout,\n components: () =>\n import('../../components/EntitySection').then(m => ({\n Content: () => compatWrapper(<m.EntitySection />),\n })),\n },\n});\n\n/**\n * NFS widget: TemplateSection (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const templateSectionWidget = HomePageWidgetBlueprint.make({\n name: 'rhdh-template-section',\n params: {\n name: 'Red Hat Developer Hub - Explore templates',\n layout: defaultCardLayout,\n components: () =>\n import('../../components/TemplateSection').then(m => ({\n Content: m.TemplateSection,\n })),\n },\n});\n\n/**\n * NFS widget: QuickAccessCard (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const quickAccessCardWidget = HomePageWidgetBlueprint.make({\n name: 'quick-access-card',\n params: {\n name: 'Quick Access Card',\n layout: defaultCardLayout,\n components: () =>\n import('../../components/QuickAccessCard').then(m => ({\n Content: () => compatWrapper(<m.QuickAccessCard />),\n })),\n },\n});\n\n/**\n * NFS widget: SearchBar (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const searchBarWidget = HomePageWidgetBlueprint.make({\n name: 'search-bar',\n params: {\n name: 'Search',\n layout: {\n ...defaultCardLayout,\n height: {\n ...defaultCardLayout.height,\n defaultRows: 2,\n minRows: 1,\n maxRows: 1,\n },\n },\n components: () =>\n import('../../components/SearchBar').then(m => ({\n Content: () => compatWrapper(<m.SearchBar />),\n })),\n },\n});\n\n/**\n * NFS widget: FeaturedDocsCard (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const featuredDocsCardWidget = HomePageWidgetBlueprint.make({\n name: 'featured-docs-card',\n params: {\n name: 'Featured docs',\n layout: defaultCardLayout,\n components: () =>\n import('../../components/FeaturedDocsCard').then(m => ({\n Content: m.FeaturedDocsCard,\n })),\n },\n});\n\n/**\n * NFS widget: CatalogStarred (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const catalogStarredWidget = homePlugin\n .getExtension('home-page-widget:home/starred-entities')\n .override({\n params: {\n name: 'CatalogStarred',\n title: 'Starred catalog entities',\n },\n });\n\n/**\n * Disables the default home plugin toolkit widget.\n * @alpha\n */\nexport const disableToolkit = homePlugin\n .getExtension('home-page-widget:home/toolkit')\n .override({\n disabled: true,\n });\n\n/**\n * NFS widget: RecentlyVisited (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const RecentlyVisitedWidget = HomePageWidgetBlueprint.make({\n name: 'recently-visited',\n params: {\n layout: defaultCardLayout,\n name: 'Recently visited',\n components: () =>\n import('@backstage/plugin-home').then(m => ({\n Content: m.HomePageRecentlyVisited,\n })),\n },\n});\n\n/**\n * NFS widget: TopVisited (migrated from mountPoint home.page/cards).\n * @alpha\n */\nexport const TopVisitedWidget = HomePageWidgetBlueprint.make({\n name: 'top-visited',\n params: {\n layout: defaultCardLayout,\n name: 'Top visited',\n components: () =>\n import('@backstage/plugin-home').then(m => ({\n Content: () => <m.HomePageTopVisited />,\n })),\n },\n});\n"],"names":[],"mappings":"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"}
package/dist/alpha.d.ts CHANGED
@@ -47,7 +47,7 @@ declare const homepageTranslationRef: _backstage_frontend_plugin_api.Translation
47
47
  readonly "entities.fetchError": string;
48
48
  readonly "entities.emptyDescription": string;
49
49
  readonly "entities.register": string;
50
- readonly "entities.viewAll": string;
50
+ readonly "entities.browseTheCatalog": string;
51
51
  }>;
52
52
 
53
53
  /**
package/dist/alpha.esm.js CHANGED
@@ -3,7 +3,7 @@ import { createFrontendModule } from '@backstage/frontend-plugin-api';
3
3
  import { onboardingSectionWidget, entitySectionWidget, templateSectionWidget, quickAccessCardWidget, featuredDocsCardWidget, searchBarWidget, TopVisitedWidget, RecentlyVisitedWidget, catalogStarredWidget, disableToolkit } from './alpha/extensions/homePageCards.esm.js';
4
4
  import { homepageTranslations } from './translations/index.esm.js';
5
5
  import { homePageLayoutExtension } from './alpha/extensions/homePageLayoutExtension.esm.js';
6
- import { quickAccessApi } from './alpha/extensions/apis.esm.js';
6
+ import { defaultWidgetsApi, quickAccessApi } from './alpha/extensions/apis.esm.js';
7
7
  export { homepageTranslationRef } from './translations/ref.esm.js';
8
8
 
9
9
  const homePageModule = createFrontendModule({
@@ -13,6 +13,7 @@ const homePageModule = createFrontendModule({
13
13
  onboardingSectionWidget,
14
14
  entitySectionWidget,
15
15
  templateSectionWidget,
16
+ defaultWidgetsApi,
16
17
  quickAccessApi,
17
18
  quickAccessCardWidget,
18
19
  featuredDocsCardWidget,
@@ -1 +1 @@
1
- {"version":3,"file":"alpha.esm.js","sources":["../src/alpha/index.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 { TranslationBlueprint } from '@backstage/plugin-app-react';\nimport { createFrontendModule } from '@backstage/frontend-plugin-api';\nimport {\n catalogStarredWidget,\n disableToolkit,\n entitySectionWidget,\n featuredDocsCardWidget,\n onboardingSectionWidget,\n quickAccessCardWidget,\n RecentlyVisitedWidget,\n searchBarWidget,\n templateSectionWidget,\n TopVisitedWidget,\n} from './extensions/homePageCards';\nimport { homepageTranslations } from '../translations';\n\nimport { homePageLayoutExtension } from './extensions/homePageLayoutExtension';\nimport { quickAccessApi } from './extensions/apis';\n\n/**\n * Frontend module for the Dynamic Home Page plugin (New Frontend System).\n *\n * Extends the `home` plugin with a custom layout and RHDH widgets: Onboarding,\n * Entity Catalog, Templates, Quick Access, Search, Recently Visited, Top Visited, etc.\n * Add to your app's `createApp({ features: [..., homePageDevModule] })`.\n *\n * @alpha\n */\nexport const homePageModule = createFrontendModule({\n pluginId: 'home',\n extensions: [\n homePageLayoutExtension,\n onboardingSectionWidget,\n entitySectionWidget,\n templateSectionWidget,\n quickAccessApi,\n quickAccessCardWidget,\n featuredDocsCardWidget,\n searchBarWidget,\n TopVisitedWidget,\n RecentlyVisitedWidget,\n catalogStarredWidget,\n disableToolkit,\n ],\n});\n\n/**\n * Translation module for the Dynamic Home Page plugin.\n *\n * @alpha\n */\nexport const homepageTranslationsModule = createFrontendModule({\n pluginId: 'app',\n extensions: [\n TranslationBlueprint.make({\n name: 'homepage-translations',\n params: {\n resource: homepageTranslations,\n },\n }),\n ],\n});\n\n/**\n *\n * @alpha\n */\nexport { homepageTranslationRef, homepageTranslations } from '../translations';\n"],"names":[],"mappings":";;;;;;;;AA4CO,MAAM,iBAAiB,oBAAqB,CAAA;AAAA,EACjD,QAAU,EAAA,MAAA;AAAA,EACV,UAAY,EAAA;AAAA,IACV,uBAAA;AAAA,IACA,uBAAA;AAAA,IACA,mBAAA;AAAA,IACA,qBAAA;AAAA,IACA,cAAA;AAAA,IACA,qBAAA;AAAA,IACA,sBAAA;AAAA,IACA,eAAA;AAAA,IACA,gBAAA;AAAA,IACA,qBAAA;AAAA,IACA,oBAAA;AAAA,IACA;AAAA;AAEJ,CAAC;AAOM,MAAM,6BAA6B,oBAAqB,CAAA;AAAA,EAC7D,QAAU,EAAA,KAAA;AAAA,EACV,UAAY,EAAA;AAAA,IACV,qBAAqB,IAAK,CAAA;AAAA,MACxB,IAAM,EAAA,uBAAA;AAAA,MACN,MAAQ,EAAA;AAAA,QACN,QAAU,EAAA;AAAA;AACZ,KACD;AAAA;AAEL,CAAC;;;;"}
1
+ {"version":3,"file":"alpha.esm.js","sources":["../src/alpha/index.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 { TranslationBlueprint } from '@backstage/plugin-app-react';\nimport { createFrontendModule } from '@backstage/frontend-plugin-api';\nimport {\n catalogStarredWidget,\n disableToolkit,\n entitySectionWidget,\n featuredDocsCardWidget,\n onboardingSectionWidget,\n quickAccessCardWidget,\n RecentlyVisitedWidget,\n searchBarWidget,\n templateSectionWidget,\n TopVisitedWidget,\n} from './extensions/homePageCards';\nimport { homepageTranslations } from '../translations';\n\nimport { homePageLayoutExtension } from './extensions/homePageLayoutExtension';\nimport { defaultWidgetsApi, quickAccessApi } from './extensions/apis';\n\n/**\n * Frontend module for the Dynamic Home Page plugin (New Frontend System).\n *\n * Extends the `home` plugin with a custom layout and RHDH widgets: Onboarding,\n * Entity Catalog, Templates, Quick Access, Search, Recently Visited, Top Visited, etc.\n * Add to your app's `createApp({ features: [..., homePageDevModule] })`.\n *\n * @alpha\n */\nexport const homePageModule = createFrontendModule({\n pluginId: 'home',\n extensions: [\n homePageLayoutExtension,\n onboardingSectionWidget,\n entitySectionWidget,\n templateSectionWidget,\n defaultWidgetsApi,\n quickAccessApi,\n quickAccessCardWidget,\n featuredDocsCardWidget,\n searchBarWidget,\n TopVisitedWidget,\n RecentlyVisitedWidget,\n catalogStarredWidget,\n disableToolkit,\n ],\n});\n\n/**\n * Translation module for the Dynamic Home Page plugin.\n *\n * @alpha\n */\nexport const homepageTranslationsModule = createFrontendModule({\n pluginId: 'app',\n extensions: [\n TranslationBlueprint.make({\n name: 'homepage-translations',\n params: {\n resource: homepageTranslations,\n },\n }),\n ],\n});\n\n/**\n *\n * @alpha\n */\nexport { homepageTranslationRef, homepageTranslations } from '../translations';\n"],"names":[],"mappings":";;;;;;;;AA4CO,MAAM,iBAAiB,oBAAqB,CAAA;AAAA,EACjD,QAAU,EAAA,MAAA;AAAA,EACV,UAAY,EAAA;AAAA,IACV,uBAAA;AAAA,IACA,uBAAA;AAAA,IACA,mBAAA;AAAA,IACA,qBAAA;AAAA,IACA,iBAAA;AAAA,IACA,cAAA;AAAA,IACA,qBAAA;AAAA,IACA,sBAAA;AAAA,IACA,eAAA;AAAA,IACA,gBAAA;AAAA,IACA,qBAAA;AAAA,IACA,oBAAA;AAAA,IACA;AAAA;AAEJ,CAAC;AAOM,MAAM,6BAA6B,oBAAqB,CAAA;AAAA,EAC7D,QAAU,EAAA,KAAA;AAAA,EACV,UAAY,EAAA;AAAA,IACV,qBAAqB,IAAK,CAAA;AAAA,MACxB,IAAM,EAAA,uBAAA;AAAA,MACN,MAAQ,EAAA;AAAA,QACN,QAAU,EAAA;AAAA;AACZ,KACD;AAAA;AAEL,CAAC;;;;"}
@@ -0,0 +1,26 @@
1
+ import { createApiRef } from '@backstage/core-plugin-api';
2
+
3
+ const defaultWidgetsApiRef = createApiRef({
4
+ id: "plugin.homepage.default-widgets"
5
+ });
6
+ class DefaultWidgetsApiClient {
7
+ discoveryApi;
8
+ fetchApi;
9
+ constructor(options) {
10
+ this.discoveryApi = options.discoveryApi;
11
+ this.fetchApi = options.fetchApi;
12
+ }
13
+ async getDefaultWidgets() {
14
+ const baseUrl = await this.discoveryApi.getBaseUrl("homepage");
15
+ const response = await this.fetchApi.fetch(`${baseUrl}/default-widgets`);
16
+ if (!response.ok) {
17
+ throw new Error(
18
+ `Failed to fetch default cards, status ${response.status}: ${response.statusText}`
19
+ );
20
+ }
21
+ return await response.json();
22
+ }
23
+ }
24
+
25
+ export { DefaultWidgetsApiClient, defaultWidgetsApiRef };
26
+ //# sourceMappingURL=DefaultWidgetsApiClient.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultWidgetsApiClient.esm.js","sources":["../../src/api/DefaultWidgetsApiClient.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 createApiRef,\n DiscoveryApi,\n FetchApi,\n} from '@backstage/core-plugin-api';\nimport type { DefaultWidgetsResponse } from '@red-hat-developer-hub/backstage-plugin-homepage-common';\n\nexport type {\n DefaultWidgetsResponse,\n VisibleDefaultWidget,\n} from '@red-hat-developer-hub/backstage-plugin-homepage-common';\n\n/**\n * @public\n */\nexport interface DefaultWidgetsApi {\n getDefaultWidgets(): Promise<DefaultWidgetsResponse>;\n}\n\n/**\n * @public\n */\nexport const defaultWidgetsApiRef = createApiRef<DefaultWidgetsApi>({\n id: 'plugin.homepage.default-widgets',\n});\n\n/**\n * @public\n */\nexport class DefaultWidgetsApiClient implements DefaultWidgetsApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: { discoveryApi: DiscoveryApi; fetchApi: FetchApi }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi;\n }\n\n async getDefaultWidgets(): Promise<DefaultWidgetsResponse> {\n const baseUrl = await this.discoveryApi.getBaseUrl('homepage');\n const response = await this.fetchApi.fetch(`${baseUrl}/default-widgets`);\n if (!response.ok) {\n throw new Error(\n `Failed to fetch default cards, status ${response.status}: ${response.statusText}`,\n );\n }\n return await response.json();\n }\n}\n"],"names":[],"mappings":";;AAsCO,MAAM,uBAAuB,YAAgC,CAAA;AAAA,EAClE,EAAI,EAAA;AACN,CAAC;AAKM,MAAM,uBAAqD,CAAA;AAAA,EAC/C,YAAA;AAAA,EACA,QAAA;AAAA,EAEjB,YAAY,OAA6D,EAAA;AACvE,IAAA,IAAA,CAAK,eAAe,OAAQ,CAAA,YAAA;AAC5B,IAAA,IAAA,CAAK,WAAW,OAAQ,CAAA,QAAA;AAAA;AAC1B,EAEA,MAAM,iBAAqD,GAAA;AACzD,IAAA,MAAM,OAAU,GAAA,MAAM,IAAK,CAAA,YAAA,CAAa,WAAW,UAAU,CAAA;AAC7D,IAAA,MAAM,WAAW,MAAM,IAAA,CAAK,SAAS,KAAM,CAAA,CAAA,EAAG,OAAO,CAAkB,gBAAA,CAAA,CAAA;AACvE,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAyC,sCAAA,EAAA,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,SAAS,UAAU,CAAA;AAAA,OAClF;AAAA;AAEF,IAAO,OAAA,MAAM,SAAS,IAAK,EAAA;AAAA;AAE/B;;;;"}
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { useMemo } from 'react';
2
+ import { useRef, useMemo } from 'react';
3
3
  import { CustomHomepageGrid } from '@backstage/plugin-home';
4
4
  import { createCardExtension } from '@backstage/plugin-home-react';
5
5
  import GlobalStyles from '@mui/material/GlobalStyles';
@@ -7,11 +7,14 @@ import { useTheme } from '@mui/material/styles';
7
7
  import 'react-grid-layout/css/styles.css';
8
8
  import { dynamicHomePagePlugin } from '../plugin.esm.js';
9
9
  import { useTranslation } from '../hooks/useTranslation.esm.js';
10
+ import { useContainerQuery } from '../hooks/useContainerQuery.esm.js';
10
11
  import { getCardTitle, getCardDescription, isCardADefaultConfiguration } from '../utils/customizable-cards.esm.js';
11
12
 
12
13
  const CustomizableGrid = ({ mountPoints }) => {
13
14
  const theme = useTheme();
14
15
  const { t } = useTranslation();
16
+ const gridContainerRef = useRef(null);
17
+ useContainerQuery(gridContainerRef, { notifyWindowResize: true });
15
18
  const { children, config } = useMemo(() => {
16
19
  const childDictionary = {};
17
20
  const defaultConfig = [];
@@ -77,13 +80,20 @@ const CustomizableGrid = ({ mountPoints }) => {
77
80
  }
78
81
  ),
79
82
  /* @__PURE__ */ jsx(
80
- CustomHomepageGrid,
83
+ "div",
81
84
  {
82
- config,
83
- preventCollision: false,
84
- compactType: "vertical",
85
- style: { margin: "-10px" },
86
- children
85
+ ref: gridContainerRef,
86
+ style: { width: "100%", minWidth: 0, boxSizing: "border-box" },
87
+ children: /* @__PURE__ */ jsx(
88
+ CustomHomepageGrid,
89
+ {
90
+ config,
91
+ preventCollision: false,
92
+ compactType: "vertical",
93
+ style: { margin: "-10px" },
94
+ children
95
+ }
96
+ )
87
97
  }
88
98
  )
89
99
  ] });
@@ -1 +1 @@
1
- {"version":3,"file":"CustomizableGrid.esm.js","sources":["../../src/components/CustomizableGrid.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// This complete read-only home page grid picks up the idea and styles from\n// https://github.com/backstage/backstage/blob/master/plugins/home\n// Esp. from the CustomHomepageGrid component:\n// https://github.com/backstage/backstage/blob/master/plugins/home/src/components/CustomHomepage/CustomHomepageGrid.tsx\n// but without the drag and drop functionality.\n\nimport type { ReactElement } from 'react';\nimport { useMemo } from 'react';\n\nimport {\n CustomHomepageGrid,\n LayoutConfiguration,\n} from '@backstage/plugin-home';\nimport {\n ComponentParts,\n createCardExtension,\n} from '@backstage/plugin-home-react';\n\nimport GlobalStyles from '@mui/material/GlobalStyles';\nimport { useTheme } from '@mui/material/styles';\n\n// Removes the doubled scrollbar\nimport 'react-grid-layout/css/styles.css';\n\nimport { HomePageCardMountPoint } from '../types';\nimport { dynamicHomePagePlugin } from '../plugin';\nimport { useTranslation } from '../hooks/useTranslation';\nimport {\n isCardADefaultConfiguration,\n getCardTitle,\n getCardDescription,\n} from '../utils/customizable-cards';\n\n/**\n * @public\n */\nexport interface CustomizableGridProps {\n mountPoints: HomePageCardMountPoint[];\n}\n\n/**\n * @public\n */\nexport const CustomizableGrid = ({ mountPoints }: CustomizableGridProps) => {\n const theme = useTheme();\n const { t } = useTranslation();\n\n const { children, config } = useMemo(() => {\n // Children contains the additional / available cards a user can add.\n // Maps the card name to the actual card component.\n // Contains also the title to allow sorting before rendering.\n const childDictionary: Record<\n string,\n { child: ReactElement; title: string | undefined }\n > = {};\n\n // Config contains the default layout of the homepage\n const defaultConfig: LayoutConfiguration[] = [];\n\n mountPoints.forEach(mountPoint => {\n if (!mountPoint.config?.id) {\n return;\n }\n const id = mountPoint.config.id;\n const title = getCardTitle(t, mountPoint);\n const description = getCardDescription(t, mountPoint);\n\n const automaticallyWrapInInfoCard = false;\n\n const componentParts: ComponentParts = {\n Content: props => (\n <mountPoint.Component {...mountPoint.config!.props} {...props} />\n ),\n // Untested and unsupported for now!\n Actions: mountPoint.Actions as () => JSX.Element,\n // Untested and unsupported for now!\n Settings: mountPoint.Settings as () => JSX.Element,\n // This is a workaround to NOT automatically wrap in an InfoCard\n ContextProvider: automaticallyWrapInInfoCard\n ? undefined\n : props => (\n <mountPoint.Component {...mountPoint.config!.props} {...props} />\n ),\n };\n\n const cardExtension = createCardExtension({\n name: id,\n title,\n description,\n layout: mountPoint.config.cardLayout,\n settings: mountPoint.config.settings,\n components: () => Promise.resolve(componentParts),\n });\n\n const Card = dynamicHomePagePlugin.provide(cardExtension);\n\n childDictionary[id] = {\n child: <Card />,\n title,\n };\n\n if (isCardADefaultConfiguration(mountPoint)) {\n const layout = mountPoint.config?.layouts?.xl || {};\n\n defaultConfig.push({\n component: id,\n x: layout.x ?? 0,\n y: layout.y ?? 0,\n width: layout.w ?? 12,\n height: layout.h ?? 4,\n movable: true,\n deletable: true,\n resizable: true,\n });\n }\n });\n\n return {\n children: Object.values(childDictionary)\n .sort((a, b) =>\n a.title && b.title ? a.title.localeCompare(b.title) : 0,\n )\n .map(e => e.child),\n config: defaultConfig,\n };\n }, [mountPoints, t]);\n\n return (\n <>\n <GlobalStyles\n styles={{\n '[class*=\"makeStyles-settingsOverlay\"]': {\n backgroundColor:\n theme.palette.mode === 'dark'\n ? 'rgba(20, 20, 20, 0.95) !important'\n : 'rgba(40, 40, 40, 0.93) !important',\n },\n }}\n />\n <CustomHomepageGrid\n config={config}\n preventCollision={false}\n compactType=\"vertical\"\n style={{ margin: '-10px' }}\n >\n {children}\n </CustomHomepageGrid>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CustomizableGrid.esm.js","sources":["../../src/components/CustomizableGrid.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// This complete read-only home page grid picks up the idea and styles from\n// https://github.com/backstage/backstage/blob/master/plugins/home\n// Esp. from the CustomHomepageGrid component:\n// https://github.com/backstage/backstage/blob/master/plugins/home/src/components/CustomHomepage/CustomHomepageGrid.tsx\n// but without the drag and drop functionality.\n\nimport type { ReactElement } from 'react';\nimport { useMemo, useRef } from 'react';\n\nimport {\n CustomHomepageGrid,\n LayoutConfiguration,\n} from '@backstage/plugin-home';\nimport {\n ComponentParts,\n createCardExtension,\n} from '@backstage/plugin-home-react';\n\nimport GlobalStyles from '@mui/material/GlobalStyles';\nimport { useTheme } from '@mui/material/styles';\n\n// Removes the doubled scrollbar\nimport 'react-grid-layout/css/styles.css';\n\nimport { HomePageCardMountPoint } from '../types';\nimport { dynamicHomePagePlugin } from '../plugin';\nimport { useTranslation } from '../hooks/useTranslation';\nimport { useContainerQuery } from '../hooks/useContainerQuery';\nimport {\n isCardADefaultConfiguration,\n getCardTitle,\n getCardDescription,\n} from '../utils/customizable-cards';\n\n/**\n * @public\n */\nexport interface CustomizableGridProps {\n mountPoints: HomePageCardMountPoint[];\n}\n\n/**\n * @public\n */\nexport const CustomizableGrid = ({ mountPoints }: CustomizableGridProps) => {\n const theme = useTheme();\n const { t } = useTranslation();\n const gridContainerRef = useRef<HTMLDivElement>(null);\n useContainerQuery(gridContainerRef, { notifyWindowResize: true });\n\n const { children, config } = useMemo(() => {\n // Children contains the additional / available cards a user can add.\n // Maps the card name to the actual card component.\n // Contains also the title to allow sorting before rendering.\n const childDictionary: Record<\n string,\n { child: ReactElement; title: string | undefined }\n > = {};\n\n // Config contains the default layout of the homepage\n const defaultConfig: LayoutConfiguration[] = [];\n\n mountPoints.forEach(mountPoint => {\n if (!mountPoint.config?.id) {\n return;\n }\n const id = mountPoint.config.id;\n const title = getCardTitle(t, mountPoint);\n const description = getCardDescription(t, mountPoint);\n\n const automaticallyWrapInInfoCard = false;\n\n const componentParts: ComponentParts = {\n Content: props => (\n <mountPoint.Component {...mountPoint.config!.props} {...props} />\n ),\n // Untested and unsupported for now!\n Actions: mountPoint.Actions as () => JSX.Element,\n // Untested and unsupported for now!\n Settings: mountPoint.Settings as () => JSX.Element,\n // This is a workaround to NOT automatically wrap in an InfoCard\n ContextProvider: automaticallyWrapInInfoCard\n ? undefined\n : props => (\n <mountPoint.Component {...mountPoint.config!.props} {...props} />\n ),\n };\n\n const cardExtension = createCardExtension({\n name: id,\n title,\n description,\n layout: mountPoint.config.cardLayout,\n settings: mountPoint.config.settings,\n components: () => Promise.resolve(componentParts),\n });\n\n const Card = dynamicHomePagePlugin.provide(cardExtension);\n\n childDictionary[id] = {\n child: <Card />,\n title,\n };\n\n if (isCardADefaultConfiguration(mountPoint)) {\n const layout = mountPoint.config?.layouts?.xl || {};\n\n defaultConfig.push({\n component: id,\n x: layout.x ?? 0,\n y: layout.y ?? 0,\n width: layout.w ?? 12,\n height: layout.h ?? 4,\n movable: true,\n deletable: true,\n resizable: true,\n });\n }\n });\n\n return {\n children: Object.values(childDictionary)\n .sort((a, b) =>\n a.title && b.title ? a.title.localeCompare(b.title) : 0,\n )\n .map(e => e.child),\n config: defaultConfig,\n };\n }, [mountPoints, t]);\n\n return (\n <>\n <GlobalStyles\n styles={{\n '[class*=\"makeStyles-settingsOverlay\"]': {\n backgroundColor:\n theme.palette.mode === 'dark'\n ? 'rgba(20, 20, 20, 0.95) !important'\n : 'rgba(40, 40, 40, 0.93) !important',\n },\n }}\n />\n <div\n ref={gridContainerRef}\n style={{ width: '100%', minWidth: 0, boxSizing: 'border-box' }}\n >\n <CustomHomepageGrid\n config={config}\n preventCollision={false}\n compactType=\"vertical\"\n style={{ margin: '-10px' }}\n >\n {children}\n </CustomHomepageGrid>\n </div>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { useRef, useMemo } from 'react';
3
+ import { CustomHomepageGrid } from '@backstage/plugin-home';
4
+ import { createCardExtension } from '@backstage/plugin-home-react';
5
+ import GlobalStyles from '@mui/material/GlobalStyles';
6
+ import { useTheme } from '@mui/material/styles';
7
+ import 'react-grid-layout/css/styles.css';
8
+ import { dynamicHomePagePlugin } from '../plugin.esm.js';
9
+ import { useTranslation } from '../hooks/useTranslation.esm.js';
10
+ import { useContainerQuery } from '../hooks/useContainerQuery.esm.js';
11
+ import { getCardTitle, getCardDescription } from '../utils/customizable-cards.esm.js';
12
+
13
+ const DefaultWidgetsCustomizableGrid = ({
14
+ defaultWidgets,
15
+ mountPoints
16
+ }) => {
17
+ const theme = useTheme();
18
+ const { t } = useTranslation();
19
+ const gridContainerRef = useRef(null);
20
+ useContainerQuery(gridContainerRef, { notifyWindowResize: true });
21
+ const mountPointsById = useMemo(() => {
22
+ const map = /* @__PURE__ */ new Map();
23
+ for (const mp of mountPoints) {
24
+ if (mp.config?.id) {
25
+ map.set(mp.config.id, mp);
26
+ }
27
+ }
28
+ return map;
29
+ }, [mountPoints]);
30
+ const widgetsToRender = useMemo(() => {
31
+ if (defaultWidgets.length > 0) {
32
+ return defaultWidgets.map((widget, index) => ({
33
+ id: widget.id || `config-widget-${index}`,
34
+ ref: widget.ref,
35
+ layout: widget.layout,
36
+ source: "config"
37
+ }));
38
+ }
39
+ return mountPoints.filter((mp) => mp.config?.id).map((mp) => ({
40
+ id: mp.config.id,
41
+ ref: mp.config.id,
42
+ layout: undefined,
43
+ source: "mountpoint"
44
+ }));
45
+ }, [defaultWidgets, mountPoints]);
46
+ const { children, config } = useMemo(() => {
47
+ const childDictionary = {};
48
+ const defaultConfig = [];
49
+ widgetsToRender.forEach((widget) => {
50
+ const widgetId = widget.id;
51
+ const widgetRef = widget.ref ?? widgetId;
52
+ if (!widgetId || !widgetRef) {
53
+ console.warn(
54
+ `Widget missing id or ref (id: ${String(widget.id)}, ref: ${String(widget.ref)}).`
55
+ );
56
+ return;
57
+ }
58
+ const mountPoint = mountPointsById.get(widgetRef);
59
+ if (!mountPoint || !mountPoint.config?.id) {
60
+ console.warn(
61
+ `No mount point found for widget ref ${widgetRef}. Available mount points: ${[...mountPointsById.keys()].join(", ")}`
62
+ );
63
+ return;
64
+ }
65
+ const title = getCardTitle(t, mountPoint);
66
+ const description = getCardDescription(t, mountPoint);
67
+ const componentParts = {
68
+ Content: (props) => /* @__PURE__ */ jsx(mountPoint.Component, { ...mountPoint.config.props, ...props }),
69
+ Actions: mountPoint.Actions,
70
+ Settings: mountPoint.Settings,
71
+ ContextProvider: (props) => /* @__PURE__ */ jsx(mountPoint.Component, { ...mountPoint.config.props, ...props })
72
+ };
73
+ const cardExtension = createCardExtension({
74
+ name: widgetId,
75
+ title,
76
+ description,
77
+ layout: mountPoint.config.cardLayout,
78
+ settings: mountPoint.config.settings,
79
+ components: () => Promise.resolve(componentParts)
80
+ });
81
+ const Card = dynamicHomePagePlugin.provide(cardExtension);
82
+ childDictionary[widgetId] = {
83
+ child: /* @__PURE__ */ jsx(Card, {}),
84
+ title
85
+ };
86
+ const widgetLayout = widget.layout;
87
+ const layout = widgetLayout?.xl ?? {};
88
+ defaultConfig.push({
89
+ component: widgetId,
90
+ x: layout.x ?? 0,
91
+ y: layout.y ?? 0,
92
+ width: layout.w ?? 12,
93
+ height: layout.h ?? 4,
94
+ movable: true,
95
+ deletable: true,
96
+ resizable: true
97
+ });
98
+ });
99
+ return {
100
+ children: Object.values(childDictionary).sort(
101
+ (a, b) => a.title && b.title ? a.title.localeCompare(b.title) : 0
102
+ ).map((e) => e.child),
103
+ config: defaultConfig
104
+ };
105
+ }, [widgetsToRender, mountPointsById, t]);
106
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
107
+ /* @__PURE__ */ jsx(
108
+ GlobalStyles,
109
+ {
110
+ styles: {
111
+ '[class*="makeStyles-settingsOverlay"]': {
112
+ backgroundColor: theme.palette.mode === "dark" ? "rgba(20, 20, 20, 0.95) !important" : "rgba(40, 40, 40, 0.93) !important"
113
+ }
114
+ }
115
+ }
116
+ ),
117
+ /* @__PURE__ */ jsx(
118
+ "div",
119
+ {
120
+ ref: gridContainerRef,
121
+ style: { width: "100%", minWidth: 0, boxSizing: "border-box" },
122
+ children: /* @__PURE__ */ jsx(
123
+ CustomHomepageGrid,
124
+ {
125
+ config,
126
+ preventCollision: false,
127
+ compactType: "vertical",
128
+ style: { margin: "-10px" },
129
+ children
130
+ }
131
+ )
132
+ }
133
+ )
134
+ ] });
135
+ };
136
+
137
+ export { DefaultWidgetsCustomizableGrid };
138
+ //# sourceMappingURL=DefaultWidgetsCustomizableGrid.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultWidgetsCustomizableGrid.esm.js","sources":["../../src/components/DefaultWidgetsCustomizableGrid.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 type { ReactElement } from 'react';\nimport { useMemo, useRef } from 'react';\n\nimport {\n CustomHomepageGrid,\n LayoutConfiguration,\n} from '@backstage/plugin-home';\nimport {\n ComponentParts,\n createCardExtension,\n} from '@backstage/plugin-home-react';\n\nimport GlobalStyles from '@mui/material/GlobalStyles';\nimport { useTheme } from '@mui/material/styles';\n\nimport 'react-grid-layout/css/styles.css';\n\nimport type { VisibleDefaultWidget } from '../api/DefaultWidgetsApiClient';\nimport { HomePageCardMountPoint } from '../types';\nimport { dynamicHomePagePlugin } from '../plugin';\nimport { useTranslation } from '../hooks/useTranslation';\nimport { useContainerQuery } from '../hooks/useContainerQuery';\nimport { getCardTitle, getCardDescription } from '../utils/customizable-cards';\n\nexport interface DefaultWidgetsCustomizableGridProps {\n defaultWidgets: VisibleDefaultWidget[];\n mountPoints: HomePageCardMountPoint[];\n}\n\nexport const DefaultWidgetsCustomizableGrid = ({\n defaultWidgets,\n mountPoints,\n}: DefaultWidgetsCustomizableGridProps) => {\n const theme = useTheme();\n const { t } = useTranslation();\n const gridContainerRef = useRef<HTMLDivElement>(null);\n useContainerQuery(gridContainerRef, { notifyWindowResize: true });\n\n const mountPointsById = useMemo(() => {\n const map = new Map<string, HomePageCardMountPoint>();\n for (const mp of mountPoints) {\n if (mp.config?.id) {\n map.set(mp.config.id, mp);\n }\n }\n return map;\n }, [mountPoints]);\n\n const widgetsToRender = useMemo(() => {\n // If config exists, use it exclusively; otherwise fall back to mount points\n if (defaultWidgets.length > 0) {\n return defaultWidgets.map((widget, index) => ({\n id: widget.id || `config-widget-${index}`,\n ref: widget.ref,\n layout: widget.layout,\n source: 'config' as const,\n }));\n }\n\n // Fallback: render all mount points\n return mountPoints\n .filter(mp => mp.config?.id)\n .map(mp => ({\n id: mp.config!.id,\n ref: mp.config!.id,\n layout: undefined,\n source: 'mountpoint' as const,\n }));\n }, [defaultWidgets, mountPoints]);\n\n const { children, config } = useMemo(() => {\n const childDictionary: Record<\n string,\n { child: ReactElement; title: string | undefined }\n > = {};\n const defaultConfig: LayoutConfiguration[] = [];\n\n widgetsToRender.forEach(widget => {\n const widgetId = widget.id;\n const widgetRef = widget.ref ?? widgetId;\n if (!widgetId || !widgetRef) {\n // eslint-disable-next-line no-console\n console.warn(\n `Widget missing id or ref (id: ${String(widget.id)}, ref: ${String(widget.ref)}).`,\n );\n return;\n }\n\n const mountPoint = mountPointsById.get(widgetRef);\n\n if (!mountPoint || !mountPoint.config?.id) {\n // eslint-disable-next-line no-console\n console.warn(\n `No mount point found for widget ref ${widgetRef}. Available mount points: ${[...mountPointsById.keys()].join(', ')}`,\n );\n return;\n }\n\n const title = getCardTitle(t, mountPoint);\n const description = getCardDescription(t, mountPoint);\n\n const automaticallyWrapInInfoCard = false;\n\n const componentParts: ComponentParts = {\n Content: props => (\n <mountPoint.Component {...mountPoint.config!.props} {...props} />\n ),\n Actions: mountPoint.Actions as () => JSX.Element,\n Settings: mountPoint.Settings as () => JSX.Element,\n ContextProvider: automaticallyWrapInInfoCard\n ? undefined\n : props => (\n <mountPoint.Component {...mountPoint.config!.props} {...props} />\n ),\n };\n\n const cardExtension = createCardExtension({\n name: widgetId,\n title,\n description,\n layout: mountPoint.config.cardLayout,\n settings: mountPoint.config.settings,\n components: () => Promise.resolve(componentParts),\n });\n\n const Card = dynamicHomePagePlugin.provide(cardExtension);\n\n childDictionary[widgetId] = {\n child: <Card />,\n title,\n };\n\n const widgetLayout = widget.layout as\n | Record<string, { x?: number; y?: number; w?: number; h?: number }>\n | undefined;\n const layout = widgetLayout?.xl ?? {};\n\n defaultConfig.push({\n component: widgetId,\n x: layout.x ?? 0,\n y: layout.y ?? 0,\n width: layout.w ?? 12,\n height: layout.h ?? 4,\n movable: true,\n deletable: true,\n resizable: true,\n });\n });\n\n return {\n children: Object.values(childDictionary)\n .sort((a, b) =>\n a.title && b.title ? a.title.localeCompare(b.title) : 0,\n )\n .map(e => e.child),\n config: defaultConfig,\n };\n }, [widgetsToRender, mountPointsById, t]);\n\n return (\n <>\n <GlobalStyles\n styles={{\n '[class*=\"makeStyles-settingsOverlay\"]': {\n backgroundColor:\n theme.palette.mode === 'dark'\n ? 'rgba(20, 20, 20, 0.95) !important'\n : 'rgba(40, 40, 40, 0.93) !important',\n },\n }}\n />\n <div\n ref={gridContainerRef}\n style={{ width: '100%', minWidth: 0, boxSizing: 'border-box' }}\n >\n <CustomHomepageGrid\n config={config}\n preventCollision={false}\n compactType=\"vertical\"\n style={{ margin: '-10px' }}\n >\n {children}\n </CustomHomepageGrid>\n </div>\n </>\n );\n};\n"],"names":[],"mappings":"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"}