@red-hat-developer-hub/backstage-plugin-dynamic-home-page 1.12.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
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
+
3
22
  ## 1.12.0
4
23
 
5
24
  ### Minor Changes
@@ -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;;;;"}
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;;;;"}
@@ -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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"}
@@ -0,0 +1,146 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useMemo } from 'react';
3
+ import { Responsive } from 'react-grid-layout';
4
+ import { ErrorBoundary } from '@backstage/core-components';
5
+ import { makeStyles } from 'tss-react/mui';
6
+ import 'react-grid-layout/css/styles.css';
7
+ import useMeasure from 'react-use/lib/useMeasure';
8
+
9
+ const gridGap = 16;
10
+ const defaultProps = {
11
+ margin: [gridGap, gridGap],
12
+ rowHeight: 60,
13
+ breakpoints: {
14
+ xl: 1600,
15
+ lg: 1200,
16
+ md: 996,
17
+ sm: 768,
18
+ xs: 480,
19
+ xxs: 0
20
+ },
21
+ cols: {
22
+ xl: 12,
23
+ lg: 12,
24
+ md: 12,
25
+ sm: 12,
26
+ xs: 12,
27
+ xxs: 12
28
+ },
29
+ isDraggable: false,
30
+ isResizable: false,
31
+ compactType: null
32
+ };
33
+ const useStyles = makeStyles()({
34
+ cardWrapper: {
35
+ '& > div[class*="MuiCard-root"]': {
36
+ width: "100%",
37
+ height: "100%"
38
+ },
39
+ '& div[class*="MuiCardContent-root"]': {
40
+ overflow: "auto"
41
+ }
42
+ }
43
+ });
44
+ const DefaultWidgetsReadOnlyGrid = ({
45
+ defaultWidgets,
46
+ mountPoints
47
+ }) => {
48
+ const { classes } = useStyles();
49
+ const [measureRef, measureRect] = useMeasure();
50
+ const mountPointsByRef = useMemo(() => {
51
+ const map = /* @__PURE__ */ new Map();
52
+ for (const mp of mountPoints) {
53
+ if (mp.config?.id) {
54
+ map.set(mp.config.id, mp);
55
+ }
56
+ }
57
+ return map;
58
+ }, [mountPoints]);
59
+ const cards = useMemo(() => {
60
+ return defaultWidgets.map((widget, index) => {
61
+ const mountPoint = mountPointsByRef.get(widget.ref);
62
+ if (!mountPoint) {
63
+ console.warn(
64
+ `No mount point found for widget with ref ${widget.ref}. Available mount points: ${[...mountPointsByRef.keys()].join(", ")}`
65
+ );
66
+ return null;
67
+ }
68
+ const id = (index + 1).toString();
69
+ const layouts2 = {};
70
+ const widgetLayout = widget.layout;
71
+ if (widgetLayout) {
72
+ for (const [breakpoint, layout] of Object.entries(widgetLayout)) {
73
+ layouts2[breakpoint] = {
74
+ i: id,
75
+ x: layout.x ?? 0,
76
+ y: layout.y ?? 0,
77
+ w: layout.w ?? 12,
78
+ h: layout.h ?? 4,
79
+ isDraggable: false,
80
+ isResizable: false
81
+ };
82
+ }
83
+ } else {
84
+ ["xl", "lg", "md", "sm", "xs", "xxs"].forEach((breakpoint) => {
85
+ layouts2[breakpoint] = {
86
+ i: id,
87
+ x: 0,
88
+ y: 0,
89
+ w: 12,
90
+ h: 4,
91
+ isDraggable: false,
92
+ isResizable: false
93
+ };
94
+ });
95
+ }
96
+ return {
97
+ id,
98
+ Component: mountPoint.Component,
99
+ props: widget.props,
100
+ layouts: layouts2
101
+ };
102
+ }).filter((card) => card !== null);
103
+ }, [defaultWidgets, mountPointsByRef]);
104
+ const layouts = useMemo(() => {
105
+ const result = {};
106
+ for (const card of cards) {
107
+ for (const [breakpoint, layoutPerBreakpoint] of Object.entries(
108
+ card.layouts
109
+ )) {
110
+ if (!result[breakpoint]) {
111
+ result[breakpoint] = [];
112
+ }
113
+ result[breakpoint].push(layoutPerBreakpoint);
114
+ }
115
+ }
116
+ return result;
117
+ }, [cards]);
118
+ const children = useMemo(() => {
119
+ return cards.map((card) => /* @__PURE__ */ jsx(
120
+ "div",
121
+ {
122
+ "data-cardid": card.id,
123
+ "data-testid": `home-page card ${card.id}`,
124
+ "data-layout": JSON.stringify(card.layouts),
125
+ className: classes.cardWrapper,
126
+ children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(card.Component, { ...card.props }) })
127
+ },
128
+ card.id
129
+ ));
130
+ }, [cards, classes.cardWrapper]);
131
+ return /* @__PURE__ */ jsxs("div", { style: { margin: -16 }, children: [
132
+ /* @__PURE__ */ jsx("div", { ref: measureRef }),
133
+ measureRect.width ? /* @__PURE__ */ jsx(
134
+ Responsive,
135
+ {
136
+ ...defaultProps,
137
+ width: measureRect.width,
138
+ layouts,
139
+ children
140
+ }
141
+ ) : null
142
+ ] });
143
+ };
144
+
145
+ export { DefaultWidgetsReadOnlyGrid };
146
+ //# sourceMappingURL=DefaultWidgetsReadOnlyGrid.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultWidgetsReadOnlyGrid.esm.js","sources":["../../src/components/DefaultWidgetsReadOnlyGrid.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 { ComponentType } from 'react';\n\nimport { useMemo } from 'react';\nimport {\n Layout,\n Layouts,\n Responsive,\n ResponsiveProps,\n} from 'react-grid-layout';\n\nimport { ErrorBoundary } from '@backstage/core-components';\n\nimport { makeStyles } from 'tss-react/mui';\n\nimport 'react-grid-layout/css/styles.css';\n\nimport useMeasure from 'react-use/lib/useMeasure';\n\nimport type { VisibleDefaultWidget } from '../api/DefaultWidgetsApiClient';\nimport { HomePageCardMountPoint } from '../types';\n\ninterface Card {\n id: string;\n Component: ComponentType<any>;\n props?: Record<string, unknown>;\n layouts: Record<string, Layout>;\n}\n\nconst gridGap = 16;\n\nconst defaultProps: ResponsiveProps = {\n margin: [gridGap, gridGap],\n rowHeight: 60,\n\n breakpoints: {\n xl: 1600,\n lg: 1200,\n md: 996,\n sm: 768,\n xs: 480,\n xxs: 0,\n },\n cols: {\n xl: 12,\n lg: 12,\n md: 12,\n sm: 12,\n xs: 12,\n xxs: 12,\n },\n\n isDraggable: false,\n isResizable: false,\n compactType: null,\n};\n\nconst useStyles = makeStyles()({\n cardWrapper: {\n '& > div[class*=\"MuiCard-root\"]': {\n width: '100%',\n height: '100%',\n },\n '& div[class*=\"MuiCardContent-root\"]': {\n overflow: 'auto',\n },\n },\n});\n\nexport interface DefaultWidgetsReadOnlyGridProps {\n defaultWidgets: VisibleDefaultWidget[];\n mountPoints: HomePageCardMountPoint[];\n}\n\nexport const DefaultWidgetsReadOnlyGrid = ({\n defaultWidgets,\n mountPoints,\n}: DefaultWidgetsReadOnlyGridProps) => {\n const { classes } = useStyles();\n const [measureRef, measureRect] = useMeasure<HTMLDivElement>();\n\n const mountPointsByRef = 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 cards = useMemo<Card[]>(() => {\n return defaultWidgets\n .map<Card | null>((widget, index) => {\n const mountPoint = mountPointsByRef.get(widget.ref);\n if (!mountPoint) {\n // eslint-disable-next-line no-console\n console.warn(\n `No mount point found for widget with ref ${widget.ref}. Available mount points: ${[...mountPointsByRef.keys()].join(', ')}`,\n );\n return null;\n }\n\n const id = (index + 1).toString();\n const layouts: Record<string, Layout> = {};\n const widgetLayout = widget.layout as\n | Record<string, { x?: number; y?: number; w?: number; h?: number }>\n | undefined;\n\n if (widgetLayout) {\n for (const [breakpoint, layout] of Object.entries(widgetLayout)) {\n layouts[breakpoint] = {\n i: id,\n x: layout.x ?? 0,\n y: layout.y ?? 0,\n w: layout.w ?? 12,\n h: layout.h ?? 4,\n isDraggable: false,\n isResizable: false,\n };\n }\n } else {\n ['xl', 'lg', 'md', 'sm', 'xs', 'xxs'].forEach(breakpoint => {\n layouts[breakpoint] = {\n i: id,\n x: 0,\n y: 0,\n w: 12,\n h: 4,\n isDraggable: false,\n isResizable: false,\n };\n });\n }\n\n return {\n id,\n Component: mountPoint.Component,\n props: widget.props,\n layouts,\n };\n })\n .filter((card): card is Card => card !== null);\n }, [defaultWidgets, mountPointsByRef]);\n\n const layouts = useMemo<Layouts>(() => {\n const result: Layouts = {};\n for (const card of cards) {\n for (const [breakpoint, layoutPerBreakpoint] of Object.entries(\n card.layouts,\n )) {\n if (!result[breakpoint]) {\n result[breakpoint] = [];\n }\n result[breakpoint].push(layoutPerBreakpoint);\n }\n }\n return result;\n }, [cards]);\n\n const children = useMemo(() => {\n return cards.map(card => (\n <div\n key={card.id}\n data-cardid={card.id}\n data-testid={`home-page card ${card.id}`}\n data-layout={JSON.stringify(card.layouts)}\n className={classes.cardWrapper}\n >\n <ErrorBoundary>\n <card.Component {...card.props} />\n </ErrorBoundary>\n </div>\n ));\n }, [cards, classes.cardWrapper]);\n\n return (\n <div style={{ margin: -gridGap }}>\n <div ref={measureRef} />\n {measureRect.width ? (\n <Responsive\n {...defaultProps}\n width={measureRect.width}\n layouts={layouts}\n >\n {children}\n </Responsive>\n ) : null}\n </div>\n );\n};\n"],"names":["layouts"],"mappings":"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"}
@@ -1,9 +1,12 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { EmptyState, Page, Content } from '@backstage/core-components';
2
+ import { EmptyState, Page, Content, Progress } from '@backstage/core-components';
3
+ import { useDefaultWidgets } from '../hooks/useDefaultWidgets.esm.js';
3
4
  import { useTranslation } from '../hooks/useTranslation.esm.js';
5
+ import { CustomizableGrid } from './CustomizableGrid.esm.js';
6
+ import { DefaultWidgetsCustomizableGrid } from './DefaultWidgetsCustomizableGrid.esm.js';
7
+ import { DefaultWidgetsReadOnlyGrid } from './DefaultWidgetsReadOnlyGrid.esm.js';
4
8
  import { Header } from './Header.esm.js';
5
9
  import { ReadOnlyGrid } from './ReadOnlyGrid.esm.js';
6
- import { CustomizableGrid } from './CustomizableGrid.esm.js';
7
10
 
8
11
  const HomePage = ({
9
12
  mountPoints,
@@ -11,8 +14,29 @@ const HomePage = ({
11
14
  ...otherProps
12
15
  }) => {
13
16
  const { t } = useTranslation();
17
+ const { defaultWidgets, loading } = useDefaultWidgets();
14
18
  let content;
15
- if (mountPoints.length === 0) {
19
+ if (loading) {
20
+ content = /* @__PURE__ */ jsx(Progress, {});
21
+ } else if (defaultWidgets && defaultWidgets.length > 0) {
22
+ if (customizable) {
23
+ content = /* @__PURE__ */ jsx(
24
+ DefaultWidgetsCustomizableGrid,
25
+ {
26
+ defaultWidgets,
27
+ mountPoints
28
+ }
29
+ );
30
+ } else {
31
+ content = /* @__PURE__ */ jsx(
32
+ DefaultWidgetsReadOnlyGrid,
33
+ {
34
+ defaultWidgets,
35
+ mountPoints
36
+ }
37
+ );
38
+ }
39
+ } else if (mountPoints.length === 0) {
16
40
  content = /* @__PURE__ */ jsx(EmptyState, { title: t("homePage.empty"), missing: "content" });
17
41
  } else if (customizable) {
18
42
  content = /* @__PURE__ */ jsx(CustomizableGrid, { mountPoints });
@@ -1 +1 @@
1
- {"version":3,"file":"HomePage.esm.js","sources":["../../src/components/HomePage.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 { Content, EmptyState, Page } from '@backstage/core-components';\n\nimport { useTranslation } from '../hooks/useTranslation';\nimport { HomePageCardMountPoint } from '../types';\nimport { Header, HeaderProps } from './Header';\nimport { ReadOnlyGrid } from './ReadOnlyGrid';\nimport { CustomizableGrid } from './CustomizableGrid';\n\nexport interface HomePageProps extends HeaderProps {\n mountPoints: HomePageCardMountPoint[];\n customizable: boolean;\n}\n\nexport const HomePage = ({\n mountPoints,\n customizable,\n ...otherProps\n}: HomePageProps) => {\n const { t } = useTranslation();\n\n let content: React.ReactNode;\n if (mountPoints.length === 0) {\n content = <EmptyState title={t('homePage.empty')} missing=\"content\" />;\n } else if (customizable) {\n content = <CustomizableGrid mountPoints={mountPoints} />;\n } else {\n content = <ReadOnlyGrid mountPoints={mountPoints} />;\n }\n\n return (\n <Page themeId=\"home\">\n <Header title={t('header.welcome')} {...otherProps} />\n <Content>{content}</Content>\n </Page>\n );\n};\n"],"names":[],"mappings":";;;;;;;AA6BO,MAAM,WAAW,CAAC;AAAA,EACvB,WAAA;AAAA,EACA,YAAA;AAAA,EACA,GAAG;AACL,CAAqB,KAAA;AACnB,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAE7B,EAAI,IAAA,OAAA;AACJ,EAAI,IAAA,WAAA,CAAY,WAAW,CAAG,EAAA;AAC5B,IAAA,OAAA,uBAAW,UAAW,EAAA,EAAA,KAAA,EAAO,EAAE,gBAAgB,CAAA,EAAG,SAAQ,SAAU,EAAA,CAAA;AAAA,aAC3D,YAAc,EAAA;AACvB,IAAU,OAAA,mBAAA,GAAA,CAAC,oBAAiB,WAA0B,EAAA,CAAA;AAAA,GACjD,MAAA;AACL,IAAU,OAAA,mBAAA,GAAA,CAAC,gBAAa,WAA0B,EAAA,CAAA;AAAA;AAGpD,EACE,uBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,OAAA,EAAQ,MACZ,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAO,KAAO,EAAA,CAAA,CAAE,gBAAgB,CAAA,EAAI,GAAG,UAAY,EAAA,CAAA;AAAA,oBACpD,GAAA,CAAC,WAAS,QAAQ,EAAA,OAAA,EAAA;AAAA,GACpB,EAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"HomePage.esm.js","sources":["../../src/components/HomePage.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 {\n Content,\n EmptyState,\n Page,\n Progress,\n} from '@backstage/core-components';\n\nimport { useDefaultWidgets } from '../hooks/useDefaultWidgets';\nimport { useTranslation } from '../hooks/useTranslation';\nimport { HomePageCardMountPoint } from '../types';\nimport { CustomizableGrid } from './CustomizableGrid';\nimport { DefaultWidgetsCustomizableGrid } from './DefaultWidgetsCustomizableGrid';\nimport { DefaultWidgetsReadOnlyGrid } from './DefaultWidgetsReadOnlyGrid';\nimport { Header, HeaderProps } from './Header';\nimport { ReadOnlyGrid } from './ReadOnlyGrid';\n\nexport interface HomePageProps extends HeaderProps {\n mountPoints: HomePageCardMountPoint[];\n customizable: boolean;\n}\n\nexport const HomePage = ({\n mountPoints,\n customizable,\n ...otherProps\n}: HomePageProps) => {\n const { t } = useTranslation();\n const { defaultWidgets, loading } = useDefaultWidgets();\n\n let content: React.ReactNode;\n if (loading) {\n content = <Progress />;\n } else if (defaultWidgets && defaultWidgets.length > 0) {\n if (customizable) {\n content = (\n <DefaultWidgetsCustomizableGrid\n defaultWidgets={defaultWidgets}\n mountPoints={mountPoints}\n />\n );\n } else {\n content = (\n <DefaultWidgetsReadOnlyGrid\n defaultWidgets={defaultWidgets}\n mountPoints={mountPoints}\n />\n );\n }\n } else if (mountPoints.length === 0) {\n content = <EmptyState title={t('homePage.empty')} missing=\"content\" />;\n } else if (customizable) {\n content = <CustomizableGrid mountPoints={mountPoints} />;\n } else {\n content = <ReadOnlyGrid mountPoints={mountPoints} />;\n }\n\n return (\n <Page themeId=\"home\">\n <Header title={t('header.welcome')} {...otherProps} />\n <Content>{content}</Content>\n </Page>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;AAqCO,MAAM,WAAW,CAAC;AAAA,EACvB,WAAA;AAAA,EACA,YAAA;AAAA,EACA,GAAG;AACL,CAAqB,KAAA;AACnB,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAC7B,EAAA,MAAM,EAAE,cAAA,EAAgB,OAAQ,EAAA,GAAI,iBAAkB,EAAA;AAEtD,EAAI,IAAA,OAAA;AACJ,EAAA,IAAI,OAAS,EAAA;AACX,IAAA,OAAA,uBAAW,QAAS,EAAA,EAAA,CAAA;AAAA,GACX,MAAA,IAAA,cAAA,IAAkB,cAAe,CAAA,MAAA,GAAS,CAAG,EAAA;AACtD,IAAA,IAAI,YAAc,EAAA;AAChB,MACE,OAAA,mBAAA,GAAA;AAAA,QAAC,8BAAA;AAAA,QAAA;AAAA,UACC,cAAA;AAAA,UACA;AAAA;AAAA,OACF;AAAA,KAEG,MAAA;AACL,MACE,OAAA,mBAAA,GAAA;AAAA,QAAC,0BAAA;AAAA,QAAA;AAAA,UACC,cAAA;AAAA,UACA;AAAA;AAAA,OACF;AAAA;AAEJ,GACF,MAAA,IAAW,WAAY,CAAA,MAAA,KAAW,CAAG,EAAA;AACnC,IAAA,OAAA,uBAAW,UAAW,EAAA,EAAA,KAAA,EAAO,EAAE,gBAAgB,CAAA,EAAG,SAAQ,SAAU,EAAA,CAAA;AAAA,aAC3D,YAAc,EAAA;AACvB,IAAU,OAAA,mBAAA,GAAA,CAAC,oBAAiB,WAA0B,EAAA,CAAA;AAAA,GACjD,MAAA;AACL,IAAU,OAAA,mBAAA,GAAA,CAAC,gBAAa,WAA0B,EAAA,CAAA;AAAA;AAGpD,EACE,uBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,OAAA,EAAQ,MACZ,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAO,KAAO,EAAA,CAAA,CAAE,gBAAgB,CAAA,EAAI,GAAG,UAAY,EAAA,CAAA;AAAA,oBACpD,GAAA,CAAC,WAAS,QAAQ,EAAA,OAAA,EAAA;AAAA,GACpB,EAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,19 @@
1
+ import { useApi } from '@backstage/core-plugin-api';
2
+ import useAsync from 'react-use/lib/useAsync';
3
+ import { defaultWidgetsApiRef } from '../api/DefaultWidgetsApiClient.esm.js';
4
+
5
+ const useDefaultWidgets = () => {
6
+ const defaultWidgetsApi = useApi(defaultWidgetsApiRef);
7
+ const { value, loading, error } = useAsync(
8
+ () => defaultWidgetsApi.getDefaultWidgets(),
9
+ [defaultWidgetsApi]
10
+ );
11
+ return {
12
+ defaultWidgets: value?.items,
13
+ loading,
14
+ error
15
+ };
16
+ };
17
+
18
+ export { useDefaultWidgets };
19
+ //# sourceMappingURL=useDefaultWidgets.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDefaultWidgets.esm.js","sources":["../../src/hooks/useDefaultWidgets.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 { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/lib/useAsync';\n\nimport {\n defaultWidgetsApiRef,\n type VisibleDefaultWidget,\n} from '../api/DefaultWidgetsApiClient';\n\nexport const useDefaultWidgets = (): {\n defaultWidgets: VisibleDefaultWidget[] | undefined;\n loading: boolean;\n error: Error | undefined;\n} => {\n const defaultWidgetsApi = useApi(defaultWidgetsApiRef);\n\n const { value, loading, error } = useAsync(\n () => defaultWidgetsApi.getDefaultWidgets(),\n [defaultWidgetsApi],\n );\n\n return {\n defaultWidgets: value?.items,\n loading,\n error,\n };\n};\n"],"names":[],"mappings":";;;;AAwBO,MAAM,oBAAoB,MAI5B;AACH,EAAM,MAAA,iBAAA,GAAoB,OAAO,oBAAoB,CAAA;AAErD,EAAA,MAAM,EAAE,KAAA,EAAO,OAAS,EAAA,KAAA,EAAU,GAAA,QAAA;AAAA,IAChC,MAAM,kBAAkB,iBAAkB,EAAA;AAAA,IAC1C,CAAC,iBAAiB;AAAA,GACpB;AAEA,EAAO,OAAA;AAAA,IACL,gBAAgB,KAAO,EAAA,KAAA;AAAA,IACvB,OAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
package/dist/index.d.ts CHANGED
@@ -2,6 +2,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
3
3
  import { ComponentType } from 'react';
4
4
  import { ClockConfig, StarredEntitiesProps, VisitedByTypeProps, FeaturedDocsCardProps } from '@backstage/plugin-home';
5
+ import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
6
+ import { DefaultWidgetsResponse } from '@red-hat-developer-hub/backstage-plugin-homepage-common';
5
7
  import { CardLayout, CardSettings } from '@backstage/plugin-home-react';
6
8
 
7
9
  /**
@@ -92,11 +94,13 @@ interface PlaceholderProps {
92
94
  /**
93
95
  * @public
94
96
  */
95
- interface WorldClockProps {
96
- worldClocks: ClockConfig[];
97
- timeFormat?: Intl.DateTimeFormatOptions;
98
- justifyContent?: 'space-between' | 'space-around';
97
+ interface DefaultWidgetsApi {
98
+ getDefaultWidgets(): Promise<DefaultWidgetsResponse>;
99
99
  }
100
+ /**
101
+ * @public
102
+ */
103
+ declare const defaultWidgetsApiRef: _backstage_frontend_plugin_api.ApiRef<DefaultWidgetsApi>;
100
104
 
101
105
  /**
102
106
  * @public
@@ -157,6 +161,15 @@ interface HomePageCardMountPoint {
157
161
  enabled?: boolean;
158
162
  }
159
163
 
164
+ /**
165
+ * @public
166
+ */
167
+ interface WorldClockProps {
168
+ worldClocks: ClockConfig[];
169
+ timeFormat?: Intl.DateTimeFormatOptions;
170
+ justifyContent?: 'space-between' | 'space-around';
171
+ }
172
+
160
173
  /**
161
174
  * Dynamic Home Page Plugin
162
175
  * @public
@@ -241,4 +254,4 @@ declare const EntitySection: () => react_jsx_runtime.JSX.Element;
241
254
  */
242
255
  declare const TemplateSection: () => react_jsx_runtime.JSX.Element;
243
256
 
244
- export { Breakpoint, CatalogStarredEntitiesCard, DynamicCustomizableHomePage, type DynamicCustomizableHomePageProps, DynamicHomePage, type DynamicHomePageProps, EntitySection, FeaturedDocsCard, Headline, type HeadlineProps, type HomePageCardMountPoint, type HomePageCardMountPointConfig, JokeCard, type Layout, type LocalClockProps, Markdown, MarkdownCard, type MarkdownCardProps, type MarkdownProps, OnboardingSection, Placeholder, type PlaceholderProps, QuickAccessCard, type QuickAccessCardProps, RecentlyVisitedCard, SearchBar, type SearchBarProps, TemplateSection, TopVisitedCard, VisitListener, WorldClock, type WorldClockProps, dynamicHomePagePlugin };
257
+ export { Breakpoint, CatalogStarredEntitiesCard, type DefaultWidgetsApi, DynamicCustomizableHomePage, type DynamicCustomizableHomePageProps, DynamicHomePage, type DynamicHomePageProps, EntitySection, FeaturedDocsCard, Headline, type HeadlineProps, type HomePageCardMountPoint, type HomePageCardMountPointConfig, JokeCard, type Layout, type LocalClockProps, Markdown, MarkdownCard, type MarkdownCardProps, type MarkdownProps, OnboardingSection, Placeholder, type PlaceholderProps, QuickAccessCard, type QuickAccessCardProps, RecentlyVisitedCard, SearchBar, type SearchBarProps, TemplateSection, TopVisitedCard, VisitListener, WorldClock, type WorldClockProps, defaultWidgetsApiRef, dynamicHomePagePlugin };
package/dist/index.esm.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export { CatalogStarredEntitiesCard, DynamicCustomizableHomePage, DynamicHomePage, EntitySection, FeaturedDocsCard, Headline, JokeCard, Markdown, MarkdownCard, OnboardingSection, Placeholder, QuickAccessCard, RecentlyVisitedCard, SearchBar, TemplateSection, TopVisitedCard, VisitListener, WorldClock, dynamicHomePagePlugin } from './plugin.esm.js';
2
+ export { defaultWidgetsApiRef } from './api/DefaultWidgetsApiClient.esm.js';
2
3
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -1,6 +1,7 @@
1
- import { createPlugin, createApiFactory, discoveryApiRef, configApiRef, identityApiRef, storageApiRef, createRoutableExtension, createComponentExtension } from '@backstage/core-plugin-api';
1
+ import { createPlugin, createApiFactory, discoveryApiRef, configApiRef, identityApiRef, fetchApiRef, storageApiRef, createRoutableExtension, createComponentExtension } from '@backstage/core-plugin-api';
2
2
  import { visitsApiRef, VisitsStorageApi } from '@backstage/plugin-home';
3
3
  import { rootRouteRef } from './routes.esm.js';
4
+ import { defaultWidgetsApiRef, DefaultWidgetsApiClient } from './api/DefaultWidgetsApiClient.esm.js';
4
5
  import { quickAccessApiRef, QuickAccessApiClient } from './api/QuickAccessApiClient.esm.js';
5
6
 
6
7
  const dynamicHomePagePlugin = createPlugin({
@@ -18,6 +19,14 @@ const dynamicHomePagePlugin = createPlugin({
18
19
  },
19
20
  factory: ({ discoveryApi, configApi, identityApi }) => new QuickAccessApiClient({ discoveryApi, configApi, identityApi })
20
21
  }),
22
+ createApiFactory({
23
+ api: defaultWidgetsApiRef,
24
+ deps: {
25
+ discoveryApi: discoveryApiRef,
26
+ fetchApi: fetchApiRef
27
+ },
28
+ factory: ({ discoveryApi, fetchApi }) => new DefaultWidgetsApiClient({ discoveryApi, fetchApi })
29
+ }),
21
30
  createApiFactory({
22
31
  api: visitsApiRef,
23
32
  deps: {
@@ -173,5 +182,5 @@ const TemplateSection = dynamicHomePagePlugin.provide(
173
182
  })
174
183
  );
175
184
 
176
- export { CatalogStarredEntitiesCard, DynamicCustomizableHomePage, DynamicHomePage, EntitySection, FeaturedDocsCard, Headline, JokeCard, Markdown, MarkdownCard, OnboardingSection, Placeholder, QuickAccessCard, RecentlyVisitedCard, SearchBar, TemplateSection, TopVisitedCard, VisitListener, WorldClock, dynamicHomePagePlugin };
185
+ export { CatalogStarredEntitiesCard, DynamicCustomizableHomePage, DynamicHomePage, EntitySection, FeaturedDocsCard, Headline, JokeCard, Markdown, MarkdownCard, OnboardingSection, Placeholder, QuickAccessCard, RecentlyVisitedCard, SearchBar, TemplateSection, TopVisitedCard, VisitListener, WorldClock, defaultWidgetsApiRef, dynamicHomePagePlugin };
177
186
  //# sourceMappingURL=plugin.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.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 type { ComponentType } from 'react';\n\nimport {\n configApiRef,\n createApiFactory,\n createComponentExtension,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n identityApiRef,\n storageApiRef,\n} from '@backstage/core-plugin-api';\n\nimport {\n type StarredEntitiesProps,\n type VisitedByTypeProps,\n type FeaturedDocsCardProps,\n visitsApiRef,\n VisitsStorageApi,\n} from '@backstage/plugin-home';\n\nimport { rootRouteRef } from './routes';\nimport { QuickAccessApiClient, quickAccessApiRef } from './api';\n\nimport type { DynamicHomePageProps } from './components/DynamicHomePage';\nimport type { DynamicCustomizableHomePageProps } from './components/DynamicCustomizableHomePage';\nimport type { SearchBarProps } from './components/SearchBar';\nimport type { QuickAccessCardProps } from './components/QuickAccessCard';\nimport type { HeadlineProps } from './components/Headline';\nimport type { MarkdownProps } from './components/Markdown';\nimport type { MarkdownCardProps } from './components/MarkdownCard';\nimport type { PlaceholderProps } from './components/Placeholder';\n\nexport type { DynamicHomePageProps } from './components/DynamicHomePage';\nexport type { DynamicCustomizableHomePageProps } from './components/DynamicCustomizableHomePage';\nexport type { SearchBarProps } from './components/SearchBar';\nexport type { QuickAccessCardProps } from './components/QuickAccessCard';\nexport type { HeadlineProps } from './components/Headline';\nexport type { MarkdownProps } from './components/Markdown';\nexport type { MarkdownCardProps } from './components/MarkdownCard';\nexport type { PlaceholderProps } from './components/Placeholder';\nexport type { LocalClockProps } from './components/LocalClock';\nexport type { WorldClockProps } from './components/WorldClock';\nexport type {\n HomePageCardMountPoint,\n HomePageCardMountPointConfig,\n Breakpoint,\n Layout,\n} from './types';\n\n/**\n * Dynamic Home Page Plugin\n * @public\n */\nexport const dynamicHomePagePlugin = createPlugin({\n id: 'dynamic-home-page',\n routes: {\n root: rootRouteRef,\n },\n apis: [\n createApiFactory({\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 createApiFactory({\n api: visitsApiRef,\n deps: {\n storageApi: storageApiRef,\n identityApi: identityApiRef,\n },\n factory: ({ storageApi, identityApi }) =>\n VisitsStorageApi.create({ storageApi, identityApi }),\n }),\n ],\n});\n\n/**\n * Dynamic Home Page\n * @public\n */\nexport const DynamicHomePage: ComponentType<DynamicHomePageProps> =\n dynamicHomePagePlugin.provide(\n createRoutableExtension({\n name: 'DynamicHomePage',\n component: () =>\n import('./components/DynamicHomePage').then(m => m.DynamicHomePage),\n mountPoint: rootRouteRef,\n }),\n );\n\n/**\n * Customizable Dynamic Home Page\n * @public\n */\nexport const DynamicCustomizableHomePage: ComponentType<DynamicCustomizableHomePageProps> =\n dynamicHomePagePlugin.provide(\n createRoutableExtension({\n name: 'DynamicCustomizableHomePage',\n component: () =>\n import('./components/DynamicCustomizableHomePage').then(\n m => m.DynamicCustomizableHomePage,\n ),\n mountPoint: rootRouteRef,\n }),\n );\n\n/**\n * @public\n */\nexport const SearchBar: ComponentType<SearchBarProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'SearchBar',\n component: {\n lazy: () => import('./components/SearchBar').then(m => m.SearchBar),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const QuickAccessCard: ComponentType<QuickAccessCardProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'QuickAccessCard',\n component: {\n lazy: () =>\n import('./components/QuickAccessCard').then(m => m.QuickAccessCard),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const Headline: ComponentType<HeadlineProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'Headline',\n component: {\n lazy: () => import('./components/Headline').then(m => m.Headline),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const Markdown: ComponentType<MarkdownProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'Markdown',\n component: {\n lazy: () => import('./components/Markdown').then(m => m.Markdown),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const MarkdownCard: ComponentType<MarkdownCardProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'MarkdownCard',\n component: {\n lazy: () =>\n import('./components/MarkdownCard').then(m => m.MarkdownCard),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const Placeholder: ComponentType<PlaceholderProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'Placeholder',\n component: {\n lazy: () => import('./components/Placeholder').then(m => m.Placeholder),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const CatalogStarredEntitiesCard: ComponentType<StarredEntitiesProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'CatalogStarredEntitiesCard',\n component: {\n lazy: () =>\n import('@backstage/plugin-home').then(m => m.HomePageStarredEntities),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const RecentlyVisitedCard: ComponentType<VisitedByTypeProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'RecentlyVisitedCard',\n component: {\n lazy: () =>\n import('@backstage/plugin-home').then(m => m.HomePageRecentlyVisited),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const TopVisitedCard: ComponentType<VisitedByTypeProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'TopVisitedCard',\n component: {\n lazy: () =>\n import('@backstage/plugin-home').then(m => m.HomePageTopVisited),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const FeaturedDocsCard: ComponentType<FeaturedDocsCardProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'FeaturedDocsCard',\n component: {\n lazy: () =>\n import('./components/FeaturedDocsCard').then(m => m.FeaturedDocsCard),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const JokeCard: ComponentType<{\n defaultCategory?: 'any' | 'programming';\n}> = dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'JokeCard',\n component: {\n lazy: () =>\n import('@backstage/plugin-home').then(m => m.HomePageRandomJoke),\n },\n }),\n);\n\n/**\n * @public\n */\nexport const VisitListener = dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'VisitListener',\n component: {\n lazy: () =>\n import('./components/VisitListener').then(m => m.VisitListener),\n },\n }),\n);\n\n/**\n * @public\n */\nexport const WorldClock = dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'WorldClock',\n component: {\n lazy: () => import('./components/WorldClock').then(m => m.WorldClock),\n },\n }),\n);\n\n/**\n * @public\n */\nexport const OnboardingSection = dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'OnboardingSection',\n component: {\n lazy: () =>\n import('./components/OnboardingSection').then(m => m.OnboardingSection),\n },\n }),\n);\n\n/**\n * @public\n */\nexport const EntitySection = dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'EntitySection',\n component: {\n lazy: () =>\n import('./components/EntitySection').then(m => m.EntitySection),\n },\n }),\n);\n\n/**\n * @public\n */\nexport const TemplateSection = dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'TemplateSection',\n component: {\n lazy: () =>\n import('./components/TemplateSection').then(m => m.TemplateSection),\n },\n }),\n);\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.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 type { ComponentType } from 'react';\n\nimport {\n configApiRef,\n createApiFactory,\n createComponentExtension,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n identityApiRef,\n storageApiRef,\n} from '@backstage/core-plugin-api';\n\nimport {\n type StarredEntitiesProps,\n type VisitedByTypeProps,\n type FeaturedDocsCardProps,\n visitsApiRef,\n VisitsStorageApi,\n} from '@backstage/plugin-home';\n\nimport { rootRouteRef } from './routes';\nimport {\n DefaultWidgetsApiClient,\n defaultWidgetsApiRef,\n QuickAccessApiClient,\n quickAccessApiRef,\n} from './api';\n\nimport type { DynamicHomePageProps } from './components/DynamicHomePage';\nimport type { DynamicCustomizableHomePageProps } from './components/DynamicCustomizableHomePage';\nimport type { SearchBarProps } from './components/SearchBar';\nimport type { QuickAccessCardProps } from './components/QuickAccessCard';\nimport type { HeadlineProps } from './components/Headline';\nimport type { MarkdownProps } from './components/Markdown';\nimport type { MarkdownCardProps } from './components/MarkdownCard';\nimport type { PlaceholderProps } from './components/Placeholder';\n\nexport { defaultWidgetsApiRef } from './api';\nexport type { DefaultWidgetsApi } from './api';\n\nexport type { DynamicHomePageProps } from './components/DynamicHomePage';\nexport type { DynamicCustomizableHomePageProps } from './components/DynamicCustomizableHomePage';\nexport type { SearchBarProps } from './components/SearchBar';\nexport type { QuickAccessCardProps } from './components/QuickAccessCard';\nexport type { HeadlineProps } from './components/Headline';\nexport type { MarkdownProps } from './components/Markdown';\nexport type { MarkdownCardProps } from './components/MarkdownCard';\nexport type { PlaceholderProps } from './components/Placeholder';\nexport type { LocalClockProps } from './components/LocalClock';\nexport type { WorldClockProps } from './components/WorldClock';\nexport type {\n HomePageCardMountPoint,\n HomePageCardMountPointConfig,\n Breakpoint,\n Layout,\n} from './types';\n\n/**\n * Dynamic Home Page Plugin\n * @public\n */\nexport const dynamicHomePagePlugin = createPlugin({\n id: 'dynamic-home-page',\n routes: {\n root: rootRouteRef,\n },\n apis: [\n createApiFactory({\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 createApiFactory({\n api: defaultWidgetsApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory: ({ discoveryApi, fetchApi }) =>\n new DefaultWidgetsApiClient({ discoveryApi, fetchApi }),\n }),\n createApiFactory({\n api: visitsApiRef,\n deps: {\n storageApi: storageApiRef,\n identityApi: identityApiRef,\n },\n factory: ({ storageApi, identityApi }) =>\n VisitsStorageApi.create({ storageApi, identityApi }),\n }),\n ],\n});\n\n/**\n * Dynamic Home Page\n * @public\n */\nexport const DynamicHomePage: ComponentType<DynamicHomePageProps> =\n dynamicHomePagePlugin.provide(\n createRoutableExtension({\n name: 'DynamicHomePage',\n component: () =>\n import('./components/DynamicHomePage').then(m => m.DynamicHomePage),\n mountPoint: rootRouteRef,\n }),\n );\n\n/**\n * Customizable Dynamic Home Page\n * @public\n */\nexport const DynamicCustomizableHomePage: ComponentType<DynamicCustomizableHomePageProps> =\n dynamicHomePagePlugin.provide(\n createRoutableExtension({\n name: 'DynamicCustomizableHomePage',\n component: () =>\n import('./components/DynamicCustomizableHomePage').then(\n m => m.DynamicCustomizableHomePage,\n ),\n mountPoint: rootRouteRef,\n }),\n );\n\n/**\n * @public\n */\nexport const SearchBar: ComponentType<SearchBarProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'SearchBar',\n component: {\n lazy: () => import('./components/SearchBar').then(m => m.SearchBar),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const QuickAccessCard: ComponentType<QuickAccessCardProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'QuickAccessCard',\n component: {\n lazy: () =>\n import('./components/QuickAccessCard').then(m => m.QuickAccessCard),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const Headline: ComponentType<HeadlineProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'Headline',\n component: {\n lazy: () => import('./components/Headline').then(m => m.Headline),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const Markdown: ComponentType<MarkdownProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'Markdown',\n component: {\n lazy: () => import('./components/Markdown').then(m => m.Markdown),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const MarkdownCard: ComponentType<MarkdownCardProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'MarkdownCard',\n component: {\n lazy: () =>\n import('./components/MarkdownCard').then(m => m.MarkdownCard),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const Placeholder: ComponentType<PlaceholderProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'Placeholder',\n component: {\n lazy: () => import('./components/Placeholder').then(m => m.Placeholder),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const CatalogStarredEntitiesCard: ComponentType<StarredEntitiesProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'CatalogStarredEntitiesCard',\n component: {\n lazy: () =>\n import('@backstage/plugin-home').then(m => m.HomePageStarredEntities),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const RecentlyVisitedCard: ComponentType<VisitedByTypeProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'RecentlyVisitedCard',\n component: {\n lazy: () =>\n import('@backstage/plugin-home').then(m => m.HomePageRecentlyVisited),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const TopVisitedCard: ComponentType<VisitedByTypeProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'TopVisitedCard',\n component: {\n lazy: () =>\n import('@backstage/plugin-home').then(m => m.HomePageTopVisited),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const FeaturedDocsCard: ComponentType<FeaturedDocsCardProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'FeaturedDocsCard',\n component: {\n lazy: () =>\n import('./components/FeaturedDocsCard').then(m => m.FeaturedDocsCard),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const JokeCard: ComponentType<{\n defaultCategory?: 'any' | 'programming';\n}> = dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'JokeCard',\n component: {\n lazy: () =>\n import('@backstage/plugin-home').then(m => m.HomePageRandomJoke),\n },\n }),\n);\n\n/**\n * @public\n */\nexport const VisitListener = dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'VisitListener',\n component: {\n lazy: () =>\n import('./components/VisitListener').then(m => m.VisitListener),\n },\n }),\n);\n\n/**\n * @public\n */\nexport const WorldClock = dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'WorldClock',\n component: {\n lazy: () => import('./components/WorldClock').then(m => m.WorldClock),\n },\n }),\n);\n\n/**\n * @public\n */\nexport const OnboardingSection = dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'OnboardingSection',\n component: {\n lazy: () =>\n import('./components/OnboardingSection').then(m => m.OnboardingSection),\n },\n }),\n);\n\n/**\n * @public\n */\nexport const EntitySection = dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'EntitySection',\n component: {\n lazy: () =>\n import('./components/EntitySection').then(m => m.EntitySection),\n },\n }),\n);\n\n/**\n * @public\n */\nexport const TemplateSection = dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'TemplateSection',\n component: {\n lazy: () =>\n import('./components/TemplateSection').then(m => m.TemplateSection),\n },\n }),\n);\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"customizable-cards.esm.js","sources":["../../src/utils/customizable-cards.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 { TranslationFunction } from '@backstage/core-plugin-api/alpha';\n\nimport { HomePageCardMountPoint } from '../types';\nimport { homepageTranslationRef } from '../translations';\nimport { getTranslatedTextWithFallback } from '../translations/utils';\n\n/**\n * Util function that decides if a `home.page/card` mount point will be rendered\n * as 'default card' or just as 'available card'.\n *\n * This is needed when customization is enabled and if customers might adopt\n * the customization in yaml feature previously.\n *\n * 1. Card mount points with a `config.layout` should be shown by default.\n * 2. Card mount points without a `config.id` should be shown by default\n * as well for backward compatibilty!\n */\nexport function isCardADefaultConfiguration(\n cardMountPoint: HomePageCardMountPoint,\n): boolean {\n return !!cardMountPoint.config?.layouts || !cardMountPoint.config?.id;\n}\n\nfunction getComponentDisplayName(\n cardMountPoint: HomePageCardMountPoint,\n): string | undefined {\n const displayName = cardMountPoint.Component.displayName;\n if (displayName?.includes('Extension(')) {\n return displayName.replace('Extension(', '').replace(')', '');\n }\n return displayName;\n}\n\nexport function getCardTitle(\n t: TranslationFunction<typeof homepageTranslationRef.T>,\n cardMountPoint: HomePageCardMountPoint,\n): string | undefined {\n return (\n getTranslatedTextWithFallback(\n t,\n cardMountPoint.config?.titleKey,\n cardMountPoint.config?.title,\n ) ?? getComponentDisplayName(cardMountPoint)\n );\n}\n\nexport function getCardDescription(\n t: TranslationFunction<typeof homepageTranslationRef.T>,\n cardMountPoint: HomePageCardMountPoint,\n): string | undefined {\n const title = getCardTitle(t, cardMountPoint);\n const description =\n getTranslatedTextWithFallback(\n t,\n cardMountPoint.config?.descriptionKey,\n cardMountPoint.config?.description,\n ) ??\n cardMountPoint.config?.props?.title ??\n cardMountPoint.config?.props?.debugContent;\n return title === description ? undefined : description;\n}\n"],"names":[],"mappings":";;AAiCO,SAAS,4BACd,cACS,EAAA;AACT,EAAA,OAAO,CAAC,CAAC,cAAA,CAAe,QAAQ,OAAW,IAAA,CAAC,eAAe,MAAQ,EAAA,EAAA;AACrE;AAEA,SAAS,wBACP,cACoB,EAAA;AACpB,EAAM,MAAA,WAAA,GAAc,eAAe,SAAU,CAAA,WAAA;AAC7C,EAAI,IAAA,WAAA,EAAa,QAAS,CAAA,YAAY,CAAG,EAAA;AACvC,IAAA,OAAO,YAAY,OAAQ,CAAA,YAAA,EAAc,EAAE,CAAE,CAAA,OAAA,CAAQ,KAAK,EAAE,CAAA;AAAA;AAE9D,EAAO,OAAA,WAAA;AACT;AAEgB,SAAA,YAAA,CACd,GACA,cACoB,EAAA;AACpB,EACE,OAAA,6BAAA;AAAA,IACE,CAAA;AAAA,IACA,eAAe,MAAQ,EAAA,QAAA;AAAA,IACvB,eAAe,MAAQ,EAAA;AAAA,GACzB,IAAK,wBAAwB,cAAc,CAAA;AAE/C;AAEgB,SAAA,kBAAA,CACd,GACA,cACoB,EAAA;AACpB,EAAM,MAAA,KAAA,GAAQ,YAAa,CAAA,CAAA,EAAG,cAAc,CAAA;AAC5C,EAAA,MAAM,WACJ,GAAA,6BAAA;AAAA,IACE,CAAA;AAAA,IACA,eAAe,MAAQ,EAAA,cAAA;AAAA,IACvB,eAAe,MAAQ,EAAA;AAAA,OAEzB,cAAe,CAAA,MAAA,EAAQ,OAAO,KAC9B,IAAA,cAAA,CAAe,QAAQ,KAAO,EAAA,YAAA;AAChC,EAAO,OAAA,KAAA,KAAU,cAAc,SAAY,GAAA,WAAA;AAC7C;;;;"}
1
+ {"version":3,"file":"customizable-cards.esm.js","sources":["../../src/utils/customizable-cards.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 { TranslationFunction } from '@backstage/core-plugin-api/alpha';\n\nimport { HomePageCardMountPoint } from '../types';\nimport { homepageTranslationRef } from '../translations';\nimport { getTranslatedTextWithFallback } from '../translations/utils';\n\n/**\n * Util function that decides if a `home.page/card` mount point will be rendered\n * as 'default card' or just as 'available card'.\n *\n * This is needed when customization is enabled and if customers might adopt\n * the customization in yaml feature previously.\n *\n * 1. Card mount points with a `config.layouts` should be shown by default.\n * 2. Card mount points without a `config.id` should be shown by default\n * as well for backward compatibilty!\n */\nexport function isCardADefaultConfiguration(\n cardMountPoint: HomePageCardMountPoint,\n): boolean {\n return !!cardMountPoint.config?.layouts || !cardMountPoint.config?.id;\n}\n\nfunction getComponentDisplayName(\n cardMountPoint: HomePageCardMountPoint,\n): string | undefined {\n const displayName = cardMountPoint.Component.displayName;\n if (displayName?.includes('Extension(')) {\n return displayName.replace('Extension(', '').replace(')', '');\n }\n return displayName;\n}\n\nexport function getCardTitle(\n t: TranslationFunction<typeof homepageTranslationRef.T>,\n cardMountPoint: HomePageCardMountPoint,\n): string | undefined {\n return (\n getTranslatedTextWithFallback(\n t,\n cardMountPoint.config?.titleKey,\n cardMountPoint.config?.title,\n ) ?? getComponentDisplayName(cardMountPoint)\n );\n}\n\nexport function getCardDescription(\n t: TranslationFunction<typeof homepageTranslationRef.T>,\n cardMountPoint: HomePageCardMountPoint,\n): string | undefined {\n const title = getCardTitle(t, cardMountPoint);\n const description =\n getTranslatedTextWithFallback(\n t,\n cardMountPoint.config?.descriptionKey,\n cardMountPoint.config?.description,\n ) ??\n cardMountPoint.config?.props?.title ??\n cardMountPoint.config?.props?.debugContent;\n return title === description ? undefined : description;\n}\n"],"names":[],"mappings":";;AAiCO,SAAS,4BACd,cACS,EAAA;AACT,EAAA,OAAO,CAAC,CAAC,cAAA,CAAe,QAAQ,OAAW,IAAA,CAAC,eAAe,MAAQ,EAAA,EAAA;AACrE;AAEA,SAAS,wBACP,cACoB,EAAA;AACpB,EAAM,MAAA,WAAA,GAAc,eAAe,SAAU,CAAA,WAAA;AAC7C,EAAI,IAAA,WAAA,EAAa,QAAS,CAAA,YAAY,CAAG,EAAA;AACvC,IAAA,OAAO,YAAY,OAAQ,CAAA,YAAA,EAAc,EAAE,CAAE,CAAA,OAAA,CAAQ,KAAK,EAAE,CAAA;AAAA;AAE9D,EAAO,OAAA,WAAA;AACT;AAEgB,SAAA,YAAA,CACd,GACA,cACoB,EAAA;AACpB,EACE,OAAA,6BAAA;AAAA,IACE,CAAA;AAAA,IACA,eAAe,MAAQ,EAAA,QAAA;AAAA,IACvB,eAAe,MAAQ,EAAA;AAAA,GACzB,IAAK,wBAAwB,cAAc,CAAA;AAE/C;AAEgB,SAAA,kBAAA,CACd,GACA,cACoB,EAAA;AACpB,EAAM,MAAA,KAAA,GAAQ,YAAa,CAAA,CAAA,EAAG,cAAc,CAAA;AAC5C,EAAA,MAAM,WACJ,GAAA,6BAAA;AAAA,IACE,CAAA;AAAA,IACA,eAAe,MAAQ,EAAA,cAAA;AAAA,IACvB,eAAe,MAAQ,EAAA;AAAA,OAEzB,cAAe,CAAA,MAAA,EAAQ,OAAO,KAC9B,IAAA,cAAA,CAAe,QAAQ,KAAO,EAAA,YAAA;AAChC,EAAO,OAAA,KAAA,KAAU,cAAc,SAAY,GAAA,WAAA;AAC7C;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@red-hat-developer-hub/backstage-plugin-dynamic-home-page",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "main": "./dist/index.esm.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -14,9 +14,11 @@
14
14
  },
15
15
  "backstage": {
16
16
  "role": "frontend-plugin",
17
- "pluginId": "@red-hat-developer-hub/backstage-plugin-dynamic-home-page",
17
+ "pluginId": "homepage",
18
18
  "pluginPackages": [
19
- "@red-hat-developer-hub/backstage-plugin-dynamic-home-page"
19
+ "@red-hat-developer-hub/backstage-plugin-dynamic-home-page",
20
+ "@red-hat-developer-hub/backstage-plugin-homepage-backend",
21
+ "@red-hat-developer-hub/backstage-plugin-homepage-common"
20
22
  ]
21
23
  },
22
24
  "exports": {
@@ -58,6 +60,7 @@
58
60
  "@backstage/catalog-model": "^1.7.7",
59
61
  "@backstage/core-components": "^0.18.8",
60
62
  "@backstage/core-plugin-api": "^1.12.4",
63
+ "@backstage/frontend-plugin-api": "^0.15.1",
61
64
  "@backstage/plugin-app-react": "^0.2.1",
62
65
  "@backstage/plugin-catalog-react": "^2.1.1",
63
66
  "@backstage/plugin-home": "^0.9.3",
@@ -68,6 +71,7 @@
68
71
  "@mui/icons-material": "5.18.0",
69
72
  "@mui/material": "5.18.0",
70
73
  "@mui/styles": "5.18.0",
74
+ "@red-hat-developer-hub/backstage-plugin-homepage-common": "^0.1.0",
71
75
  "@scalprum/react-core": "0.11.1",
72
76
  "react-grid-layout": "1.5.3",
73
77
  "react-use": "17.6.0",
@@ -87,7 +91,7 @@
87
91
  "@backstage/test-utils": "^1.7.16",
88
92
  "@backstage/ui": "^0.13.2",
89
93
  "@openshift/dynamic-plugin-sdk": "5.0.1",
90
- "@red-hat-developer-hub/backstage-plugin-theme": "^0.13.0",
94
+ "@red-hat-developer-hub/backstage-plugin-theme": "^0.14.1",
91
95
  "@testing-library/jest-dom": "6.9.1",
92
96
  "@testing-library/react": "14.3.1",
93
97
  "@testing-library/user-event": "14.6.1",