@red-hat-developer-hub/backstage-plugin-dynamic-home-page 1.0.3 → 1.2.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 (41) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/api/QuickAccessApiClient.esm.js.map +1 -1
  3. package/dist/components/CustomizableGrid.esm.js +77 -0
  4. package/dist/components/CustomizableGrid.esm.js.map +1 -0
  5. package/dist/components/CustomizableHomePage.esm.js +29 -0
  6. package/dist/components/CustomizableHomePage.esm.js.map +1 -0
  7. package/dist/components/DynamicCustomizableHomePage.esm.js +11 -0
  8. package/dist/components/DynamicCustomizableHomePage.esm.js.map +1 -0
  9. package/dist/components/DynamicHomePage.esm.js +5 -24
  10. package/dist/components/DynamicHomePage.esm.js.map +1 -1
  11. package/dist/components/FeaturedDocsCard.esm.js.map +1 -1
  12. package/dist/components/Header.esm.js +47 -0
  13. package/dist/components/Header.esm.js.map +1 -0
  14. package/dist/components/Headline.esm.js.map +1 -1
  15. package/dist/components/HomePage.esm.js +29 -0
  16. package/dist/components/HomePage.esm.js.map +1 -0
  17. package/dist/components/LocalClock.esm.js +64 -0
  18. package/dist/components/LocalClock.esm.js.map +1 -0
  19. package/dist/components/Markdown.esm.js.map +1 -1
  20. package/dist/components/MarkdownCard.esm.js.map +1 -1
  21. package/dist/components/Placeholder.esm.js +2 -2
  22. package/dist/components/Placeholder.esm.js.map +1 -1
  23. package/dist/components/QuickAccessCard.esm.js.map +1 -1
  24. package/dist/components/ReadOnlyGrid.esm.js +1 -1
  25. package/dist/components/ReadOnlyGrid.esm.js.map +1 -1
  26. package/dist/components/SearchBar.esm.js.map +1 -1
  27. package/dist/components/VisitListener.esm.js +5 -5
  28. package/dist/components/VisitListener.esm.js.map +1 -1
  29. package/dist/components/WorldClock.esm.js +19 -0
  30. package/dist/components/WorldClock.esm.js.map +1 -0
  31. package/dist/hooks/useDynamicHomePageCards.esm.js +10 -0
  32. package/dist/hooks/useDynamicHomePageCards.esm.js.map +1 -0
  33. package/dist/hooks/useQuickAccessLinks.esm.js.map +1 -1
  34. package/dist/index.d.ts +50 -2
  35. package/dist/index.esm.js +1 -1
  36. package/dist/plugin.esm.js +18 -1
  37. package/dist/plugin.esm.js.map +1 -1
  38. package/dist/routes.esm.js.map +1 -1
  39. package/package.json +24 -17
  40. package/dist/hooks/useHomePageMountPoints.esm.js +0 -10
  41. package/dist/hooks/useHomePageMountPoints.esm.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # @red-hat-developer-hub/backstage-plugin-dynamic-home-page
2
2
 
3
+ ## 1.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - a75760c: add the ability to let users customize their homepage grid layout using the [Backstage Customizable homepage component](https://github.com/backstage/backstage/blob/master/plugins/home/README.md#customizable-home-page).
8
+
9
+ This change does not affect the original `HomePage` as it introduces this new capability through new components. So, the user has a choice of choosing its HomePage implementation via the plugin configuration (dynamic routes).
10
+
11
+ ### Patch Changes
12
+
13
+ - 1a25bba: Updated dependency `react-router-dom` to `6.30.0`.
14
+ - 3dce00f: Updated dependency `react-router-dom` to `6.29.0`.
15
+ - 680ede5: Updated dependency `@mui/icons-material` to `5.16.14`.
16
+ Updated dependency `@mui/styles` to `5.16.14`.
17
+ Updated dependency `@mui/material` to `5.16.14`.
18
+ Updated dependency `@mui/styled-engine` to `5.16.14`.
19
+
20
+ ## 1.1.0
21
+
22
+ ### Minor Changes
23
+
24
+ - 4d622ad: - Added support to show also the the username (`displayName` from the user catalog entity) in the header title.
25
+ - Added additional options to show the local time and a worldclock to the header.
26
+ - Added a new `WorldClock` card based on the Home plugin `HeaderWorldClock` component to show additional clocks/timezones also in the home page content area.
27
+ - c376011: Upgrade Backstage from 0.32.0 to 1.35.0
28
+
29
+ ### Patch Changes
30
+
31
+ - 34c138c: Updated dependency `react-router-dom` to `6.28.2`.
32
+ - bc85b86: Updated dependency `tss-react` to `4.9.15`.
33
+
3
34
  ## 1.0.3
4
35
 
5
36
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"QuickAccessApiClient.esm.js","sources":["../../src/api/QuickAccessApiClient.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ConfigApi,\n createApiRef,\n DiscoveryApi,\n IdentityApi,\n} from '@backstage/core-plugin-api';\n\nimport { QuickAccessLink } from '../types';\n\nconst DEFAULT_PROXY_PATH = '/developer-hub';\n\nexport interface QuickAccessApi {\n getQuickAccessLinks(path?: string): Promise<QuickAccessLink[]>;\n}\n\nexport const quickAccessApiRef = createApiRef<QuickAccessApi>({\n id: 'app.developer-hub.quick-access.service',\n});\n\nexport type Options = {\n discoveryApi: DiscoveryApi;\n configApi: ConfigApi;\n identityApi: IdentityApi;\n};\n\nexport class QuickAccessApiClient implements QuickAccessApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly configApi: ConfigApi;\n private readonly identityApi: IdentityApi;\n\n constructor(options: Options) {\n this.discoveryApi = options.discoveryApi;\n this.configApi = options.configApi;\n this.identityApi = options.identityApi;\n }\n\n private async getBaseUrl() {\n const proxyPath =\n this.configApi.getOptionalString('developerHub.proxyPath') ??\n DEFAULT_PROXY_PATH;\n return `${await this.discoveryApi.getBaseUrl('proxy')}${proxyPath}`;\n }\n\n private async fetcher(url: string) {\n const { token: idToken } = await this.identityApi.getCredentials();\n const response = await fetch(url, {\n headers: {\n 'Content-Type': 'application/json',\n ...(idToken && { Authorization: `Bearer ${idToken}` }),\n },\n });\n if (!response.ok) {\n throw new Error(\n `failed to fetch data, status ${response.status}: ${response.statusText}`,\n );\n }\n return await response.json();\n }\n\n async getQuickAccessLinks(path?: string) {\n const proxyUrl = await this.getBaseUrl();\n const data = await this.fetcher(path ? `${proxyUrl}${path}` : proxyUrl);\n return data;\n }\n}\n"],"names":[],"mappings":";;AAwBA,MAAM,kBAAqB,GAAA,gBAAA;AAMpB,MAAM,oBAAoB,YAA6B,CAAA;AAAA,EAC5D,EAAI,EAAA;AACN,CAAC;AAQM,MAAM,oBAA+C,CAAA;AAAA,EACzC,YAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EAEjB,YAAY,OAAkB,EAAA;AAC5B,IAAA,IAAA,CAAK,eAAe,OAAQ,CAAA,YAAA;AAC5B,IAAA,IAAA,CAAK,YAAY,OAAQ,CAAA,SAAA;AACzB,IAAA,IAAA,CAAK,cAAc,OAAQ,CAAA,WAAA;AAAA;AAC7B,EAEA,MAAc,UAAa,GAAA;AACzB,IAAA,MAAM,SACJ,GAAA,IAAA,CAAK,SAAU,CAAA,iBAAA,CAAkB,wBAAwB,CACzD,IAAA,kBAAA;AACF,IAAO,OAAA,CAAA,EAAG,MAAM,IAAK,CAAA,YAAA,CAAa,WAAW,OAAO,CAAC,GAAG,SAAS,CAAA,CAAA;AAAA;AACnE,EAEA,MAAc,QAAQ,GAAa,EAAA;AACjC,IAAA,MAAM,EAAE,KAAO,EAAA,OAAA,KAAY,MAAM,IAAA,CAAK,YAAY,cAAe,EAAA;AACjE,IAAM,MAAA,QAAA,GAAW,MAAM,KAAA,CAAM,GAAK,EAAA;AAAA,MAChC,OAAS,EAAA;AAAA,QACP,cAAgB,EAAA,kBAAA;AAAA,QAChB,GAAI,OAAW,IAAA,EAAE,aAAe,EAAA,CAAA,OAAA,EAAU,OAAO,CAAG,CAAA;AAAA;AACtD,KACD,CAAA;AACD,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAgC,6BAAA,EAAA,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,SAAS,UAAU,CAAA;AAAA,OACzE;AAAA;AAEF,IAAO,OAAA,MAAM,SAAS,IAAK,EAAA;AAAA;AAC7B,EAEA,MAAM,oBAAoB,IAAe,EAAA;AACvC,IAAM,MAAA,QAAA,GAAW,MAAM,IAAA,CAAK,UAAW,EAAA;AACvC,IAAM,MAAA,IAAA,GAAO,MAAM,IAAA,CAAK,OAAQ,CAAA,IAAA,GAAO,GAAG,QAAQ,CAAA,EAAG,IAAI,CAAA,CAAA,GAAK,QAAQ,CAAA;AACtE,IAAO,OAAA,IAAA;AAAA;AAEX;;;;"}
1
+ {"version":3,"file":"QuickAccessApiClient.esm.js","sources":["../../src/api/QuickAccessApiClient.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 ConfigApi,\n createApiRef,\n DiscoveryApi,\n IdentityApi,\n} from '@backstage/core-plugin-api';\n\nimport { QuickAccessLink } from '../types';\n\nconst DEFAULT_PROXY_PATH = '/developer-hub';\n\nexport interface QuickAccessApi {\n getQuickAccessLinks(path?: string): Promise<QuickAccessLink[]>;\n}\n\nexport const quickAccessApiRef = createApiRef<QuickAccessApi>({\n id: 'app.developer-hub.quick-access.service',\n});\n\nexport type Options = {\n discoveryApi: DiscoveryApi;\n configApi: ConfigApi;\n identityApi: IdentityApi;\n};\n\nexport class QuickAccessApiClient implements QuickAccessApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly configApi: ConfigApi;\n private readonly identityApi: IdentityApi;\n\n constructor(options: Options) {\n this.discoveryApi = options.discoveryApi;\n this.configApi = options.configApi;\n this.identityApi = options.identityApi;\n }\n\n private async getBaseUrl() {\n const proxyPath =\n this.configApi.getOptionalString('developerHub.proxyPath') ??\n DEFAULT_PROXY_PATH;\n return `${await this.discoveryApi.getBaseUrl('proxy')}${proxyPath}`;\n }\n\n private async fetcher(url: string) {\n const { token: idToken } = await this.identityApi.getCredentials();\n const response = await fetch(url, {\n headers: {\n 'Content-Type': 'application/json',\n ...(idToken && { Authorization: `Bearer ${idToken}` }),\n },\n });\n if (!response.ok) {\n throw new Error(\n `failed to fetch data, status ${response.status}: ${response.statusText}`,\n );\n }\n return await response.json();\n }\n\n async getQuickAccessLinks(path?: string) {\n const proxyUrl = await this.getBaseUrl();\n const data = await this.fetcher(path ? `${proxyUrl}${path}` : proxyUrl);\n return data;\n }\n}\n"],"names":[],"mappings":";;AAyBA,MAAM,kBAAqB,GAAA,gBAAA;AAMpB,MAAM,oBAAoB,YAA6B,CAAA;AAAA,EAC5D,EAAI,EAAA;AACN,CAAC;AAQM,MAAM,oBAA+C,CAAA;AAAA,EACzC,YAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EAEjB,YAAY,OAAkB,EAAA;AAC5B,IAAA,IAAA,CAAK,eAAe,OAAQ,CAAA,YAAA;AAC5B,IAAA,IAAA,CAAK,YAAY,OAAQ,CAAA,SAAA;AACzB,IAAA,IAAA,CAAK,cAAc,OAAQ,CAAA,WAAA;AAAA;AAC7B,EAEA,MAAc,UAAa,GAAA;AACzB,IAAA,MAAM,SACJ,GAAA,IAAA,CAAK,SAAU,CAAA,iBAAA,CAAkB,wBAAwB,CACzD,IAAA,kBAAA;AACF,IAAO,OAAA,CAAA,EAAG,MAAM,IAAK,CAAA,YAAA,CAAa,WAAW,OAAO,CAAC,GAAG,SAAS,CAAA,CAAA;AAAA;AACnE,EAEA,MAAc,QAAQ,GAAa,EAAA;AACjC,IAAA,MAAM,EAAE,KAAO,EAAA,OAAA,KAAY,MAAM,IAAA,CAAK,YAAY,cAAe,EAAA;AACjE,IAAM,MAAA,QAAA,GAAW,MAAM,KAAA,CAAM,GAAK,EAAA;AAAA,MAChC,OAAS,EAAA;AAAA,QACP,cAAgB,EAAA,kBAAA;AAAA,QAChB,GAAI,OAAW,IAAA,EAAE,aAAe,EAAA,CAAA,OAAA,EAAU,OAAO,CAAG,CAAA;AAAA;AACtD,KACD,CAAA;AACD,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAgC,6BAAA,EAAA,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,SAAS,UAAU,CAAA;AAAA,OACzE;AAAA;AAEF,IAAO,OAAA,MAAM,SAAS,IAAK,EAAA;AAAA;AAC7B,EAEA,MAAM,oBAAoB,IAAe,EAAA;AACvC,IAAM,MAAA,QAAA,GAAW,MAAM,IAAA,CAAK,UAAW,EAAA;AACvC,IAAM,MAAA,IAAA,GAAO,MAAM,IAAA,CAAK,OAAQ,CAAA,IAAA,GAAO,GAAG,QAAQ,CAAA,EAAG,IAAI,CAAA,CAAA,GAAK,QAAQ,CAAA;AACtE,IAAO,OAAA,IAAA;AAAA;AAEX;;;;"}
@@ -0,0 +1,77 @@
1
+ import React, { useMemo } from 'react';
2
+ import { ErrorBoundary } from '@backstage/core-components';
3
+ import { CustomHomepageGrid } from '@backstage/plugin-home';
4
+ import { makeStyles } from 'tss-react/mui';
5
+ import 'react-grid-layout/css/styles.css';
6
+
7
+ const useStyles = makeStyles()({
8
+ // Make card content scrollable (so that cards don't overlap)
9
+ cardWrapper: {
10
+ '& > div[class*="MuiCard-root"]': {
11
+ width: "100%",
12
+ height: "100%"
13
+ },
14
+ '& div[class*="MuiCardContent-root"]': {
15
+ overflow: "auto"
16
+ }
17
+ }
18
+ });
19
+ const CustomizableGrid = (props) => {
20
+ const { classes } = useStyles();
21
+ const cards = useMemo(() => {
22
+ return props.mountPoints.map((mountPoint, index) => {
23
+ const id = (index + 1).toString();
24
+ const layouts = {};
25
+ if (mountPoint.config?.layouts) {
26
+ for (const [breakpoint, layout] of Object.entries(
27
+ mountPoint.config.layouts
28
+ )) {
29
+ layouts[breakpoint] = {
30
+ i: id,
31
+ x: layout.x ?? 0,
32
+ y: layout.y ?? 0,
33
+ w: layout.w ?? 12,
34
+ h: layout.h ?? 4,
35
+ isDraggable: false,
36
+ isResizable: false
37
+ };
38
+ }
39
+ } else {
40
+ ["xl", "lg", "md", "sm", "xs", "xxs"].forEach((breakpoint) => {
41
+ layouts[breakpoint] = {
42
+ i: id,
43
+ x: 0,
44
+ y: 0,
45
+ w: 12,
46
+ h: 4,
47
+ isDraggable: false,
48
+ isResizable: false
49
+ };
50
+ });
51
+ }
52
+ return {
53
+ id,
54
+ Component: mountPoint.Component,
55
+ props: mountPoint.config?.props,
56
+ layouts
57
+ };
58
+ });
59
+ }, [props.mountPoints]);
60
+ const children = useMemo(() => {
61
+ return cards.map((card) => /* @__PURE__ */ React.createElement(
62
+ "div",
63
+ {
64
+ key: card.id,
65
+ "data-cardid": card.id,
66
+ "data-testid": `home-page card ${card.id}`,
67
+ "data-layout": JSON.stringify(card.layouts),
68
+ className: classes.cardWrapper
69
+ },
70
+ /* @__PURE__ */ React.createElement(ErrorBoundary, null, /* @__PURE__ */ React.createElement(card.Component, { ...card.props }))
71
+ ));
72
+ }, [cards, classes.cardWrapper]);
73
+ return /* @__PURE__ */ React.createElement(CustomHomepageGrid, null, children);
74
+ };
75
+
76
+ export { CustomizableGrid };
77
+ //# sourceMappingURL=CustomizableGrid.esm.js.map
@@ -0,0 +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 React, { useMemo } from 'react';\nimport { Layout } from 'react-grid-layout';\n\nimport { ErrorBoundary } from '@backstage/core-components';\nimport { CustomHomepageGrid } from '@backstage/plugin-home';\n\nimport { makeStyles } from 'tss-react/mui';\n\n// Removes the doubled scrollbar\nimport 'react-grid-layout/css/styles.css';\n\nimport { HomePageCardMountPoint } from '../types';\n\ninterface Card {\n id: string;\n Component: React.ComponentType<any>;\n props?: Record<string, any>;\n layouts: Record<string, Layout>;\n}\n\nconst useStyles = makeStyles()({\n // Make card content scrollable (so that cards don't overlap)\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\n/**\n * @public\n */\nexport interface CustomizableGridProps {\n mountPoints: HomePageCardMountPoint[];\n breakpoints?: Record<string, number>;\n cols?: Record<string, number>;\n}\n\n/**\n * @public\n */\nexport const CustomizableGrid = (props: CustomizableGridProps) => {\n const { classes } = useStyles();\n\n const cards = useMemo<Card[]>(() => {\n return props.mountPoints.map<Card>((mountPoint, index) => {\n const id = (index + 1).toString();\n const layouts: Record<string, Layout> = {};\n\n if (mountPoint.config?.layouts) {\n for (const [breakpoint, layout] of Object.entries(\n mountPoint.config.layouts,\n )) {\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 // Default layout for cards without a layout configuration\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: mountPoint.config?.props,\n layouts,\n };\n });\n }, [props.mountPoints]);\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 <CustomHomepageGrid>{children}</CustomHomepageGrid>;\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import React, { useMemo } from 'react';
2
+ import { Page, Content, EmptyState } from '@backstage/core-components';
3
+ import { Header } from './Header.esm.js';
4
+ import { CustomizableGrid } from './CustomizableGrid.esm.js';
5
+
6
+ const CustomizableHomePage = (props) => {
7
+ const filteredAndSortedHomePageCards = useMemo(() => {
8
+ if (!props.cards) {
9
+ return [];
10
+ }
11
+ const filteredAndSorted = props.cards.filter(
12
+ (card) => card.enabled !== false && (!card.config?.priority || card.config.priority >= 0)
13
+ );
14
+ filteredAndSorted.sort(
15
+ (a, b) => (b.config?.priority ?? 0) - (a.config?.priority ?? 0)
16
+ );
17
+ return filteredAndSorted;
18
+ }, [props.cards]);
19
+ return /* @__PURE__ */ React.createElement(Page, { themeId: "home" }, /* @__PURE__ */ React.createElement(Header, { ...props }), /* @__PURE__ */ React.createElement(Content, null, filteredAndSortedHomePageCards.length === 0 ? /* @__PURE__ */ React.createElement(
20
+ EmptyState,
21
+ {
22
+ title: "No home page cards (mount points) configured or found.",
23
+ missing: "content"
24
+ }
25
+ ) : /* @__PURE__ */ React.createElement(CustomizableGrid, { mountPoints: filteredAndSortedHomePageCards })));
26
+ };
27
+
28
+ export { CustomizableHomePage };
29
+ //# sourceMappingURL=CustomizableHomePage.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CustomizableHomePage.esm.js","sources":["../../src/components/CustomizableHomePage.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 React, { useMemo } from 'react';\n\nimport { Content, EmptyState, Page } from '@backstage/core-components';\n\nimport { HomePageCardMountPoint } from '../types';\n\nimport { Header, HeaderProps } from './Header';\nimport { CustomizableGrid } from './CustomizableGrid';\n\nexport interface HomePageProps extends HeaderProps {\n cards?: HomePageCardMountPoint[];\n}\n\nexport const CustomizableHomePage = (props: HomePageProps) => {\n const filteredAndSortedHomePageCards = useMemo(() => {\n if (!props.cards) {\n return [];\n }\n\n const filteredAndSorted = props.cards.filter(\n card =>\n card.enabled !== false &&\n (!card.config?.priority || card.config.priority >= 0),\n );\n\n filteredAndSorted.sort(\n (a, b) => (b.config?.priority ?? 0) - (a.config?.priority ?? 0),\n );\n\n return filteredAndSorted;\n }, [props.cards]);\n\n return (\n <Page themeId=\"home\">\n <Header {...props} />\n <Content>\n {filteredAndSortedHomePageCards.length === 0 ? (\n <EmptyState\n title=\"No home page cards (mount points) configured or found.\"\n missing=\"content\"\n />\n ) : (\n <CustomizableGrid mountPoints={filteredAndSortedHomePageCards} />\n )}\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":";;;;;AA6Ba,MAAA,oBAAA,GAAuB,CAAC,KAAyB,KAAA;AAC5D,EAAM,MAAA,8BAAA,GAAiC,QAAQ,MAAM;AACnD,IAAI,IAAA,CAAC,MAAM,KAAO,EAAA;AAChB,MAAA,OAAO,EAAC;AAAA;AAGV,IAAM,MAAA,iBAAA,GAAoB,MAAM,KAAM,CAAA,MAAA;AAAA,MACpC,CAAA,IAAA,KACE,IAAK,CAAA,OAAA,KAAY,KAChB,KAAA,CAAC,KAAK,MAAQ,EAAA,QAAA,IAAY,IAAK,CAAA,MAAA,CAAO,QAAY,IAAA,CAAA;AAAA,KACvD;AAEA,IAAkB,iBAAA,CAAA,IAAA;AAAA,MAChB,CAAC,GAAG,CAAO,KAAA,CAAA,CAAA,CAAE,QAAQ,QAAY,IAAA,CAAA,KAAM,CAAE,CAAA,MAAA,EAAQ,QAAY,IAAA,CAAA;AAAA,KAC/D;AAEA,IAAO,OAAA,iBAAA;AAAA,GACN,EAAA,CAAC,KAAM,CAAA,KAAK,CAAC,CAAA;AAEhB,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,OAAQ,EAAA,MAAA,EAAA,kBACX,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,EAAQ,GAAG,KAAA,EAAO,CACnB,kBAAA,KAAA,CAAA,aAAA,CAAC,OACE,EAAA,IAAA,EAAA,8BAAA,CAA+B,WAAW,CACzC,mBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,KAAM,EAAA,wDAAA;AAAA,MACN,OAAQ,EAAA;AAAA;AAAA,sBAGT,KAAA,CAAA,aAAA,CAAA,gBAAA,EAAA,EAAiB,WAAa,EAAA,8BAAA,EAAgC,CAEnE,CACF,CAAA;AAEJ;;;;"}
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { useDynamicHomePageCards } from '../hooks/useDynamicHomePageCards.esm.js';
3
+ import { CustomizableHomePage } from './CustomizableHomePage.esm.js';
4
+
5
+ const DynamicCustomizableHomePage = (props) => {
6
+ const cards = useDynamicHomePageCards();
7
+ return /* @__PURE__ */ React.createElement(CustomizableHomePage, { ...props, cards });
8
+ };
9
+
10
+ export { DynamicCustomizableHomePage };
11
+ //# sourceMappingURL=DynamicCustomizableHomePage.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DynamicCustomizableHomePage.esm.js","sources":["../../src/components/DynamicCustomizableHomePage.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 React from 'react';\n\nimport type { ClockConfig } from '@backstage/plugin-home';\n\nimport { useDynamicHomePageCards } from '../hooks/useDynamicHomePageCards';\nimport { CustomizableHomePage } from './CustomizableHomePage';\nimport type { LocalClockProps } from './LocalClock';\n\n/**\n * This type is similar to Omit&lt;HomePageProps, 'cards'&gt;.\n * We redefine it here to avoid the need to export HomePageProps to the API export!\n * @public\n */\nexport interface DynamicCustomizableHomePageProps {\n title?: string;\n personalizedTitle?: string;\n pageTitle?: string;\n subtitle?: string;\n localClock?: LocalClockProps;\n worldClocks?: ClockConfig[];\n}\n\n/**\n * @public\n */\nexport const DynamicCustomizableHomePage = (\n props: DynamicCustomizableHomePageProps,\n) => {\n const cards = useDynamicHomePageCards();\n\n return <CustomizableHomePage {...props} cards={cards} />;\n};\n"],"names":[],"mappings":";;;;AAyCa,MAAA,2BAAA,GAA8B,CACzC,KACG,KAAA;AACH,EAAA,MAAM,QAAQ,uBAAwB,EAAA;AAEtC,EAAA,uBAAQ,KAAA,CAAA,aAAA,CAAA,oBAAA,EAAA,EAAsB,GAAG,KAAA,EAAO,KAAc,EAAA,CAAA;AACxD;;;;"}
@@ -1,29 +1,10 @@
1
- import React, { useMemo } from 'react';
2
- import { Page, Header, Content, EmptyState } from '@backstage/core-components';
3
- import { useHomePageMountPoints } from '../hooks/useHomePageMountPoints.esm.js';
4
- import { ReadOnlyGrid } from './ReadOnlyGrid.esm.js';
1
+ import React from 'react';
2
+ import { useDynamicHomePageCards } from '../hooks/useDynamicHomePageCards.esm.js';
3
+ import { HomePage } from './HomePage.esm.js';
5
4
 
6
5
  const DynamicHomePage = (props) => {
7
- const allHomePageMountPoints = useHomePageMountPoints();
8
- const filteredAndSortedHomePageCards = useMemo(() => {
9
- if (!allHomePageMountPoints) {
10
- return [];
11
- }
12
- const filteredAndSorted = allHomePageMountPoints.filter(
13
- (card) => card.enabled !== false && (!card.config?.priority || card.config.priority >= 0)
14
- );
15
- filteredAndSorted.sort(
16
- (a, b) => (b.config?.priority ?? 0) - (a.config?.priority ?? 0)
17
- );
18
- return filteredAndSorted;
19
- }, [allHomePageMountPoints]);
20
- return /* @__PURE__ */ React.createElement(Page, { themeId: "home" }, /* @__PURE__ */ React.createElement(Header, { title: props.title ?? "Welcome back!" }), /* @__PURE__ */ React.createElement(Content, null, filteredAndSortedHomePageCards.length === 0 ? /* @__PURE__ */ React.createElement(
21
- EmptyState,
22
- {
23
- title: "No home page cards (mount points) configured or found.",
24
- missing: "content"
25
- }
26
- ) : /* @__PURE__ */ React.createElement(ReadOnlyGrid, { mountPoints: filteredAndSortedHomePageCards })));
6
+ const cards = useDynamicHomePageCards();
7
+ return /* @__PURE__ */ React.createElement(HomePage, { ...props, cards });
27
8
  };
28
9
 
29
10
  export { DynamicHomePage };
@@ -1 +1 @@
1
- {"version":3,"file":"DynamicHomePage.esm.js","sources":["../../src/components/DynamicHomePage.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, { useMemo } from 'react';\n\nimport { Content, EmptyState, Header, Page } from '@backstage/core-components';\n\nimport { useHomePageMountPoints } from '../hooks/useHomePageMountPoints';\nimport { ReadOnlyGrid } from './ReadOnlyGrid';\n\n/**\n * @public\n */\nexport interface DynamicHomePageProps {\n title?: string;\n}\n\n/**\n * @public\n */\nexport const DynamicHomePage = (props: DynamicHomePageProps) => {\n const allHomePageMountPoints = useHomePageMountPoints();\n\n const filteredAndSortedHomePageCards = useMemo(() => {\n if (!allHomePageMountPoints) {\n return [];\n }\n\n const filteredAndSorted = allHomePageMountPoints.filter(\n card =>\n card.enabled !== false &&\n (!card.config?.priority || card.config.priority >= 0),\n );\n\n filteredAndSorted.sort(\n (a, b) => (b.config?.priority ?? 0) - (a.config?.priority ?? 0),\n );\n\n return filteredAndSorted;\n }, [allHomePageMountPoints]);\n\n return (\n <Page themeId=\"home\">\n <Header title={props.title ?? 'Welcome back!'} />\n <Content>\n {filteredAndSortedHomePageCards.length === 0 ? (\n <EmptyState\n title=\"No home page cards (mount points) configured or found.\"\n missing=\"content\"\n />\n ) : (\n <ReadOnlyGrid mountPoints={filteredAndSortedHomePageCards} />\n )}\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":";;;;;AAgCa,MAAA,eAAA,GAAkB,CAAC,KAAgC,KAAA;AAC9D,EAAA,MAAM,yBAAyB,sBAAuB,EAAA;AAEtD,EAAM,MAAA,8BAAA,GAAiC,QAAQ,MAAM;AACnD,IAAA,IAAI,CAAC,sBAAwB,EAAA;AAC3B,MAAA,OAAO,EAAC;AAAA;AAGV,IAAA,MAAM,oBAAoB,sBAAuB,CAAA,MAAA;AAAA,MAC/C,CAAA,IAAA,KACE,IAAK,CAAA,OAAA,KAAY,KAChB,KAAA,CAAC,KAAK,MAAQ,EAAA,QAAA,IAAY,IAAK,CAAA,MAAA,CAAO,QAAY,IAAA,CAAA;AAAA,KACvD;AAEA,IAAkB,iBAAA,CAAA,IAAA;AAAA,MAChB,CAAC,GAAG,CAAO,KAAA,CAAA,CAAA,CAAE,QAAQ,QAAY,IAAA,CAAA,KAAM,CAAE,CAAA,MAAA,EAAQ,QAAY,IAAA,CAAA;AAAA,KAC/D;AAEA,IAAO,OAAA,iBAAA;AAAA,GACT,EAAG,CAAC,sBAAsB,CAAC,CAAA;AAE3B,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,OAAQ,EAAA,MAAA,EAAA,sCACX,MAAO,EAAA,EAAA,KAAA,EAAO,KAAM,CAAA,KAAA,IAAS,iBAAiB,CAC/C,kBAAA,KAAA,CAAA,aAAA,CAAC,OACE,EAAA,IAAA,EAAA,8BAAA,CAA+B,WAAW,CACzC,mBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,KAAM,EAAA,wDAAA;AAAA,MACN,OAAQ,EAAA;AAAA;AAAA,sBAGT,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA,EAAa,WAAa,EAAA,8BAAA,EAAgC,CAE/D,CACF,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"DynamicHomePage.esm.js","sources":["../../src/components/DynamicHomePage.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 React from 'react';\n\nimport type { ClockConfig } from '@backstage/plugin-home';\n\nimport { useDynamicHomePageCards } from '../hooks/useDynamicHomePageCards';\nimport { HomePage } from './HomePage';\nimport type { LocalClockProps } from './LocalClock';\n\n/**\n * This type is similar to Omit&lt;HomePageProps, 'cards'&gt;.\n * We redefine it here to avoid the need to export HomePageProps to the API export!\n * @public\n */\nexport interface DynamicHomePageProps {\n title?: string;\n personalizedTitle?: string;\n pageTitle?: string;\n subtitle?: string;\n localClock?: LocalClockProps;\n worldClocks?: ClockConfig[];\n}\n\n/**\n * @public\n */\nexport const DynamicHomePage = (props: DynamicHomePageProps) => {\n const cards = useDynamicHomePageCards();\n\n return <HomePage {...props} cards={cards} />;\n};\n"],"names":[],"mappings":";;;;AAyCa,MAAA,eAAA,GAAkB,CAAC,KAAgC,KAAA;AAC9D,EAAA,MAAM,QAAQ,uBAAwB,EAAA;AAEtC,EAAA,uBAAQ,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA,EAAU,GAAG,KAAA,EAAO,KAAc,EAAA,CAAA;AAC5C;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"FeaturedDocsCard.esm.js","sources":["../../src/components/FeaturedDocsCard.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\n\nimport {\n FeaturedDocsCard as PluginHomeFeaturedDocsCard,\n FeaturedDocsCardProps,\n} from '@backstage/plugin-home';\n\n/**\n * Overrides `FeaturedDocsCard` from the home plugin, but overrides the\n * `subLinkText` prop to be \" Learn more\" instead of \"LEARN MORE\".\n *\n * 1. To fix the all uppercase that is used in home plugin\n * 2. To add a small missing gap between the title and the button\n */\nexport const FeaturedDocsCard = (props: FeaturedDocsCardProps) => {\n return <PluginHomeFeaturedDocsCard subLinkText=\" Learn more\" {...props} />;\n};\n"],"names":["PluginHomeFeaturedDocsCard"],"mappings":";;;AA6Ba,MAAA,gBAAA,GAAmB,CAAC,KAAiC,KAAA;AAChE,EAAA,uBAAQ,KAAA,CAAA,aAAA,CAAAA,kBAAA,EAAA,EAA2B,WAAY,EAAA,aAAA,EAAe,GAAG,KAAO,EAAA,CAAA;AAC1E;;;;"}
1
+ {"version":3,"file":"FeaturedDocsCard.esm.js","sources":["../../src/components/FeaturedDocsCard.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 React from 'react';\n\nimport {\n FeaturedDocsCard as PluginHomeFeaturedDocsCard,\n FeaturedDocsCardProps,\n} from '@backstage/plugin-home';\n\n/**\n * Overrides `FeaturedDocsCard` from the home plugin, but overrides the\n * `subLinkText` prop to be \" Learn more\" instead of \"LEARN MORE\".\n *\n * 1. To fix the all uppercase that is used in home plugin\n * 2. To add a small missing gap between the title and the button\n */\nexport const FeaturedDocsCard = (props: FeaturedDocsCardProps) => {\n return <PluginHomeFeaturedDocsCard subLinkText=\" Learn more\" {...props} />;\n};\n"],"names":["PluginHomeFeaturedDocsCard"],"mappings":";;;AA8Ba,MAAA,gBAAA,GAAmB,CAAC,KAAiC,KAAA;AAChE,EAAA,uBAAQ,KAAA,CAAA,aAAA,CAAAA,kBAAA,EAAA,EAA2B,WAAY,EAAA,aAAA,EAAe,GAAG,KAAO,EAAA,CAAA;AAC1E;;;;"}
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+ import { useApi, identityApiRef } from '@backstage/core-plugin-api';
3
+ import { Header as Header$1 } from '@backstage/core-components';
4
+ import { HeaderWorldClock } from '@backstage/plugin-home';
5
+ import useAsync from 'react-use/esm/useAsync';
6
+ import { LocalClock } from './LocalClock.esm.js';
7
+
8
+ const getPersonalizedTitle = (title, displayName) => {
9
+ const firstName = displayName?.split(" ")[0];
10
+ const replacedTitle = title.replace("{{firstName}}", firstName ?? "").replace("{{displayName}}", displayName ?? "");
11
+ return replacedTitle;
12
+ };
13
+ const Header = (props) => {
14
+ const identityApi = useApi(identityApiRef);
15
+ const { value: profile } = useAsync(() => identityApi.getProfileInfo());
16
+ const title = React.useMemo(() => {
17
+ if (profile?.displayName && props.personalizedTitle) {
18
+ return getPersonalizedTitle(props.personalizedTitle, profile.displayName);
19
+ } else if (props.title) {
20
+ return getPersonalizedTitle(props.title, profile?.displayName);
21
+ }
22
+ return getPersonalizedTitle("Welcome back!", profile?.displayName);
23
+ }, [profile?.displayName, props.personalizedTitle, props.title]);
24
+ const subtitle = React.useMemo(() => {
25
+ return props.subtitle ? getPersonalizedTitle(props.subtitle, profile?.displayName) : undefined;
26
+ }, [props.subtitle, profile?.displayName]);
27
+ return /* @__PURE__ */ React.createElement(
28
+ Header$1,
29
+ {
30
+ title,
31
+ subtitle,
32
+ pageTitleOverride: props.pageTitle
33
+ },
34
+ props.localClock?.format && props.localClock?.format !== "none" ? /* @__PURE__ */ React.createElement(
35
+ LocalClock,
36
+ {
37
+ label: props.localClock?.label ?? (props.worldClocks && props.worldClocks.length > 0 ? "Local" : undefined),
38
+ format: props.localClock?.format ?? (props.worldClocks && props.worldClocks.length > 0 ? "time" : undefined),
39
+ lang: props.localClock?.lang
40
+ }
41
+ ) : null,
42
+ props.worldClocks && props.worldClocks.length > 0 ? /* @__PURE__ */ React.createElement(HeaderWorldClock, { clockConfigs: props.worldClocks }) : null
43
+ );
44
+ };
45
+
46
+ export { Header, getPersonalizedTitle };
47
+ //# sourceMappingURL=Header.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Header.esm.js","sources":["../../src/components/Header.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 React from 'react';\n\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\nimport { Header as BackstageHeader } from '@backstage/core-components';\nimport { ClockConfig, HeaderWorldClock } from '@backstage/plugin-home';\n\nimport useAsync from 'react-use/esm/useAsync';\n\nimport { LocalClock, LocalClockProps } from './LocalClock';\n\nexport interface HeaderProps {\n title?: string;\n personalizedTitle?: string;\n pageTitle?: string;\n subtitle?: string;\n localClock?: LocalClockProps;\n worldClocks?: ClockConfig[];\n}\n\n// I kept this because I hope that we will add this soon or at least in Dynamic Home Page plugin 1.2 ~ RHDH 1.6.\n// const getTimeBasedTitle = (): string => {\n// const currentHour = new Date(Date.now()).getHours();\n// if (currentHour < 12) {\n// return 'Good morning {{firstName}}';\n// } else if (currentHour < 17) {\n// return 'Good afternoon {{firstName}}';\n// }\n// return 'Good evening {{firstName}}';\n// };\n\nexport const getPersonalizedTitle = (\n title: string,\n displayName: string | undefined,\n) => {\n const firstName = displayName?.split(' ')[0];\n const replacedTitle = title\n .replace('{{firstName}}', firstName ?? '')\n .replace('{{displayName}}', displayName ?? '');\n return replacedTitle;\n};\n\nexport const Header = (props: HeaderProps) => {\n const identityApi = useApi(identityApiRef);\n const { value: profile } = useAsync(() => identityApi.getProfileInfo());\n\n const title = React.useMemo<string>(() => {\n if (profile?.displayName && props.personalizedTitle) {\n return getPersonalizedTitle(props.personalizedTitle, profile.displayName);\n } else if (props.title) {\n return getPersonalizedTitle(props.title, profile?.displayName);\n }\n // return getPersonalizedTitle(getTimeBasedTitle(), profile?.displayName);\n return getPersonalizedTitle('Welcome back!', profile?.displayName);\n }, [profile?.displayName, props.personalizedTitle, props.title]);\n\n const subtitle = React.useMemo<string | undefined>(() => {\n return props.subtitle\n ? getPersonalizedTitle(props.subtitle, profile?.displayName)\n : undefined;\n }, [props.subtitle, profile?.displayName]);\n\n return (\n <BackstageHeader\n title={title}\n subtitle={subtitle}\n pageTitleOverride={props.pageTitle}\n >\n {props.localClock?.format && props.localClock?.format !== 'none' ? (\n <LocalClock\n label={\n props.localClock?.label ??\n (props.worldClocks && props.worldClocks.length > 0\n ? 'Local'\n : undefined)\n }\n format={\n props.localClock?.format ??\n (props.worldClocks && props.worldClocks.length > 0\n ? 'time'\n : undefined)\n }\n lang={props.localClock?.lang}\n />\n ) : null}\n\n {props.worldClocks && props.worldClocks.length > 0 ? (\n <HeaderWorldClock clockConfigs={props.worldClocks} />\n ) : null}\n </BackstageHeader>\n );\n};\n"],"names":["BackstageHeader"],"mappings":";;;;;;;AA8Ca,MAAA,oBAAA,GAAuB,CAClC,KAAA,EACA,WACG,KAAA;AACH,EAAA,MAAM,SAAY,GAAA,WAAA,EAAa,KAAM,CAAA,GAAG,EAAE,CAAC,CAAA;AAC3C,EAAM,MAAA,aAAA,GAAgB,KACnB,CAAA,OAAA,CAAQ,eAAiB,EAAA,SAAA,IAAa,EAAE,CACxC,CAAA,OAAA,CAAQ,iBAAmB,EAAA,WAAA,IAAe,EAAE,CAAA;AAC/C,EAAO,OAAA,aAAA;AACT;AAEa,MAAA,MAAA,GAAS,CAAC,KAAuB,KAAA;AAC5C,EAAM,MAAA,WAAA,GAAc,OAAO,cAAc,CAAA;AACzC,EAAM,MAAA,EAAE,OAAO,OAAQ,EAAA,GAAI,SAAS,MAAM,WAAA,CAAY,gBAAgB,CAAA;AAEtE,EAAM,MAAA,KAAA,GAAQ,KAAM,CAAA,OAAA,CAAgB,MAAM;AACxC,IAAI,IAAA,OAAA,EAAS,WAAe,IAAA,KAAA,CAAM,iBAAmB,EAAA;AACnD,MAAA,OAAO,oBAAqB,CAAA,KAAA,CAAM,iBAAmB,EAAA,OAAA,CAAQ,WAAW,CAAA;AAAA,KAC1E,MAAA,IAAW,MAAM,KAAO,EAAA;AACtB,MAAA,OAAO,oBAAqB,CAAA,KAAA,CAAM,KAAO,EAAA,OAAA,EAAS,WAAW,CAAA;AAAA;AAG/D,IAAO,OAAA,oBAAA,CAAqB,eAAiB,EAAA,OAAA,EAAS,WAAW,CAAA;AAAA,GACnE,EAAG,CAAC,OAAS,EAAA,WAAA,EAAa,MAAM,iBAAmB,EAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AAE/D,EAAM,MAAA,QAAA,GAAW,KAAM,CAAA,OAAA,CAA4B,MAAM;AACvD,IAAA,OAAO,MAAM,QACT,GAAA,oBAAA,CAAqB,MAAM,QAAU,EAAA,OAAA,EAAS,WAAW,CACzD,GAAA,SAAA;AAAA,KACH,CAAC,KAAA,CAAM,QAAU,EAAA,OAAA,EAAS,WAAW,CAAC,CAAA;AAEzC,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAACA,QAAA;AAAA,IAAA;AAAA,MACC,KAAA;AAAA,MACA,QAAA;AAAA,MACA,mBAAmB,KAAM,CAAA;AAAA,KAAA;AAAA,IAExB,MAAM,UAAY,EAAA,MAAA,IAAU,KAAM,CAAA,UAAA,EAAY,WAAW,MACxD,mBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,KAAA,EACE,KAAM,CAAA,UAAA,EAAY,KACjB,KAAA,KAAA,CAAM,eAAe,KAAM,CAAA,WAAA,CAAY,MAAS,GAAA,CAAA,GAC7C,OACA,GAAA,SAAA,CAAA;AAAA,QAEN,MAAA,EACE,KAAM,CAAA,UAAA,EAAY,MACjB,KAAA,KAAA,CAAM,eAAe,KAAM,CAAA,WAAA,CAAY,MAAS,GAAA,CAAA,GAC7C,MACA,GAAA,SAAA,CAAA;AAAA,QAEN,IAAA,EAAM,MAAM,UAAY,EAAA;AAAA;AAAA,KAExB,GAAA,IAAA;AAAA,IAEH,KAAA,CAAM,WAAe,IAAA,KAAA,CAAM,WAAY,CAAA,MAAA,GAAS,CAC/C,mBAAA,KAAA,CAAA,aAAA,CAAC,gBAAiB,EAAA,EAAA,YAAA,EAAc,KAAM,CAAA,WAAA,EAAa,CACjD,GAAA;AAAA,GACN;AAEJ;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Headline.esm.js","sources":["../../src/components/Headline.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\n\n/**\n * @public\n */\nexport interface HeadlineProps {\n title?: string;\n align?: 'left' | 'center' | 'right';\n}\n\n/**\n * @public\n */\nexport const Headline = (props: HeadlineProps) => {\n return <h1 style={{ textAlign: props.align }}>{props.title}</h1>;\n};\n"],"names":[],"mappings":";;AA4Ba,MAAA,QAAA,GAAW,CAAC,KAAyB,KAAA;AAChD,EAAO,uBAAA,KAAA,CAAA,aAAA,CAAC,QAAG,KAAO,EAAA,EAAE,WAAW,KAAM,CAAA,KAAA,EAAU,EAAA,EAAA,KAAA,CAAM,KAAM,CAAA;AAC7D;;;;"}
1
+ {"version":3,"file":"Headline.esm.js","sources":["../../src/components/Headline.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 React from 'react';\n\n/**\n * @public\n */\nexport interface HeadlineProps {\n title?: string;\n align?: 'left' | 'center' | 'right';\n}\n\n/**\n * @public\n */\nexport const Headline = (props: HeadlineProps) => {\n return <h1 style={{ textAlign: props.align }}>{props.title}</h1>;\n};\n"],"names":[],"mappings":";;AA6Ba,MAAA,QAAA,GAAW,CAAC,KAAyB,KAAA;AAChD,EAAO,uBAAA,KAAA,CAAA,aAAA,CAAC,QAAG,KAAO,EAAA,EAAE,WAAW,KAAM,CAAA,KAAA,EAAU,EAAA,EAAA,KAAA,CAAM,KAAM,CAAA;AAC7D;;;;"}
@@ -0,0 +1,29 @@
1
+ import React, { useMemo } from 'react';
2
+ import { Page, Content, EmptyState } from '@backstage/core-components';
3
+ import { Header } from './Header.esm.js';
4
+ import { ReadOnlyGrid } from './ReadOnlyGrid.esm.js';
5
+
6
+ const HomePage = (props) => {
7
+ const filteredAndSortedHomePageCards = useMemo(() => {
8
+ if (!props.cards) {
9
+ return [];
10
+ }
11
+ const filteredAndSorted = props.cards.filter(
12
+ (card) => card.enabled !== false && (!card.config?.priority || card.config.priority >= 0)
13
+ );
14
+ filteredAndSorted.sort(
15
+ (a, b) => (b.config?.priority ?? 0) - (a.config?.priority ?? 0)
16
+ );
17
+ return filteredAndSorted;
18
+ }, [props.cards]);
19
+ return /* @__PURE__ */ React.createElement(Page, { themeId: "home" }, /* @__PURE__ */ React.createElement(Header, { ...props }), /* @__PURE__ */ React.createElement(Content, null, filteredAndSortedHomePageCards.length === 0 ? /* @__PURE__ */ React.createElement(
20
+ EmptyState,
21
+ {
22
+ title: "No home page cards (mount points) configured or found.",
23
+ missing: "content"
24
+ }
25
+ ) : /* @__PURE__ */ React.createElement(ReadOnlyGrid, { mountPoints: filteredAndSortedHomePageCards })));
26
+ };
27
+
28
+ export { HomePage };
29
+ //# sourceMappingURL=HomePage.esm.js.map
@@ -0,0 +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 React, { useMemo } from 'react';\n\nimport { Content, EmptyState, Page } from '@backstage/core-components';\n\nimport { HomePageCardMountPoint } from '../types';\n\nimport { Header, HeaderProps } from './Header';\nimport { ReadOnlyGrid } from './ReadOnlyGrid';\n\nexport interface HomePageProps extends HeaderProps {\n cards?: HomePageCardMountPoint[];\n}\n\nexport const HomePage = (props: HomePageProps) => {\n const filteredAndSortedHomePageCards = useMemo(() => {\n if (!props.cards) {\n return [];\n }\n\n const filteredAndSorted = props.cards.filter(\n card =>\n card.enabled !== false &&\n (!card.config?.priority || card.config.priority >= 0),\n );\n\n filteredAndSorted.sort(\n (a, b) => (b.config?.priority ?? 0) - (a.config?.priority ?? 0),\n );\n\n return filteredAndSorted;\n }, [props.cards]);\n\n return (\n <Page themeId=\"home\">\n <Header {...props} />\n <Content>\n {filteredAndSortedHomePageCards.length === 0 ? (\n <EmptyState\n title=\"No home page cards (mount points) configured or found.\"\n missing=\"content\"\n />\n ) : (\n <ReadOnlyGrid mountPoints={filteredAndSortedHomePageCards} />\n )}\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":";;;;;AA6Ba,MAAA,QAAA,GAAW,CAAC,KAAyB,KAAA;AAChD,EAAM,MAAA,8BAAA,GAAiC,QAAQ,MAAM;AACnD,IAAI,IAAA,CAAC,MAAM,KAAO,EAAA;AAChB,MAAA,OAAO,EAAC;AAAA;AAGV,IAAM,MAAA,iBAAA,GAAoB,MAAM,KAAM,CAAA,MAAA;AAAA,MACpC,CAAA,IAAA,KACE,IAAK,CAAA,OAAA,KAAY,KAChB,KAAA,CAAC,KAAK,MAAQ,EAAA,QAAA,IAAY,IAAK,CAAA,MAAA,CAAO,QAAY,IAAA,CAAA;AAAA,KACvD;AAEA,IAAkB,iBAAA,CAAA,IAAA;AAAA,MAChB,CAAC,GAAG,CAAO,KAAA,CAAA,CAAA,CAAE,QAAQ,QAAY,IAAA,CAAA,KAAM,CAAE,CAAA,MAAA,EAAQ,QAAY,IAAA,CAAA;AAAA,KAC/D;AAEA,IAAO,OAAA,iBAAA;AAAA,GACN,EAAA,CAAC,KAAM,CAAA,KAAK,CAAC,CAAA;AAEhB,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,OAAQ,EAAA,MAAA,EAAA,kBACX,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,EAAQ,GAAG,KAAA,EAAO,CACnB,kBAAA,KAAA,CAAA,aAAA,CAAC,OACE,EAAA,IAAA,EAAA,8BAAA,CAA+B,WAAW,CACzC,mBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,KAAM,EAAA,wDAAA;AAAA,MACN,OAAQ,EAAA;AAAA;AAAA,sBAGT,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA,EAAa,WAAa,EAAA,8BAAA,EAAgC,CAE/D,CACF,CAAA;AAEJ;;;;"}
@@ -0,0 +1,64 @@
1
+ import React from 'react';
2
+ import { HeaderLabel } from '@backstage/core-components';
3
+
4
+ const LocalClock = (props) => {
5
+ const format = props.format ?? "time";
6
+ const lang = props.lang ?? window.navigator.language;
7
+ const [time, setTime] = React.useState(() => /* @__PURE__ */ new Date());
8
+ React.useEffect(() => {
9
+ if (format === "none") {
10
+ return () => null;
11
+ }
12
+ const intervalId = setInterval(() => setTime(/* @__PURE__ */ new Date()), 1e3);
13
+ return () => clearInterval(intervalId);
14
+ }, [format]);
15
+ if (format === "none") {
16
+ return null;
17
+ }
18
+ try {
19
+ const includeDate = format === "full" || format === "date" || format === "datewithweekday" || format === "both";
20
+ const includeTime = format === "full" || format === "time" || format === "timewithseconds" || format === "both";
21
+ const value = format === "date" || format === "datewithweekday" ? time.toLocaleDateString(lang, {
22
+ weekday: format === "datewithweekday" ? "long" : void 0,
23
+ day: "2-digit",
24
+ month: "2-digit",
25
+ year: "numeric"
26
+ }) : time.toLocaleTimeString(lang, {
27
+ weekday: format === "full" ? "long" : void 0,
28
+ day: includeDate ? "2-digit" : void 0,
29
+ month: includeDate ? "2-digit" : void 0,
30
+ year: includeDate ? "numeric" : void 0,
31
+ hour: includeTime ? "2-digit" : void 0,
32
+ minute: includeTime ? "2-digit" : void 0,
33
+ second: format === "timewithseconds" ? "2-digit" : void 0
34
+ });
35
+ const dateTime = time.toLocaleTimeString(lang, {
36
+ day: "2-digit",
37
+ month: "2-digit",
38
+ year: "numeric",
39
+ hour: "2-digit",
40
+ minute: "2-digit",
41
+ hour12: false
42
+ });
43
+ return /* @__PURE__ */ React.createElement(
44
+ HeaderLabel,
45
+ {
46
+ label: props.label ?? "",
47
+ value: /* @__PURE__ */ React.createElement(
48
+ "time",
49
+ {
50
+ dateTime,
51
+ style: props.label ? {} : { fontSize: "20px", fontWeight: "bold" }
52
+ },
53
+ value
54
+ )
55
+ }
56
+ );
57
+ } catch (e) {
58
+ console.warn("Failed to render clock", e);
59
+ return null;
60
+ }
61
+ };
62
+
63
+ export { LocalClock };
64
+ //# sourceMappingURL=LocalClock.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalClock.esm.js","sources":["../../src/components/LocalClock.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 React from 'react';\n\nimport { HeaderLabel } from '@backstage/core-components';\n\n/**\n * @public\n */\nexport interface LocalClockProps {\n label?: string;\n format?:\n | 'none'\n | 'full'\n | 'date'\n | 'datewithweekday'\n | 'time'\n | 'timewithseconds'\n | 'both';\n lang?: string;\n}\n\n/**\n * @public\n */\nexport const LocalClock = (props: LocalClockProps) => {\n const format = props.format ?? 'time';\n const lang = props.lang ?? window.navigator.language;\n\n const [time, setTime] = React.useState(() => new Date());\n\n // Could be optimized to only update the time when needed, but it's aligned with\n // https://github.com/backstage/backstage/blob/master/plugins/home/src/homePageComponents/HeaderWorldClock/HeaderWorldClock.tsx for now\n React.useEffect(() => {\n if (format === 'none') {\n return () => null;\n }\n const intervalId = setInterval(() => setTime(new Date()), 1000);\n return () => clearInterval(intervalId);\n }, [format]);\n\n if (format === 'none') {\n return null;\n }\n\n try {\n const includeDate =\n format === 'full' ||\n format === 'date' ||\n format === 'datewithweekday' ||\n format === 'both';\n const includeTime =\n format === 'full' ||\n format === 'time' ||\n format === 'timewithseconds' ||\n format === 'both';\n\n const value =\n format === 'date' || format === 'datewithweekday'\n ? time.toLocaleDateString(lang, {\n weekday: format === 'datewithweekday' ? 'long' : undefined,\n day: '2-digit',\n month: '2-digit',\n year: 'numeric',\n })\n : time.toLocaleTimeString(lang, {\n weekday: format === 'full' ? 'long' : undefined,\n day: includeDate ? '2-digit' : undefined,\n month: includeDate ? '2-digit' : undefined,\n year: includeDate ? 'numeric' : undefined,\n hour: includeTime ? '2-digit' : undefined,\n minute: includeTime ? '2-digit' : undefined,\n second: format === 'timewithseconds' ? '2-digit' : undefined,\n });\n const dateTime = time.toLocaleTimeString(lang, {\n day: '2-digit',\n month: '2-digit',\n year: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n });\n\n return (\n <HeaderLabel\n label={props.label ?? ''}\n value={\n <time\n dateTime={dateTime}\n style={props.label ? {} : { fontSize: '20px', fontWeight: 'bold' }}\n >\n {value}\n </time>\n }\n />\n );\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn('Failed to render clock', e);\n return null;\n }\n};\n"],"names":[],"mappings":";;;AAuCa,MAAA,UAAA,GAAa,CAAC,KAA2B,KAAA;AACpD,EAAM,MAAA,MAAA,GAAS,MAAM,MAAU,IAAA,MAAA;AAC/B,EAAA,MAAM,IAAO,GAAA,KAAA,CAAM,IAAQ,IAAA,MAAA,CAAO,SAAU,CAAA,QAAA;AAE5C,EAAM,MAAA,CAAC,MAAM,OAAO,CAAA,GAAI,MAAM,QAAS,CAAA,sBAAU,IAAA,IAAA,EAAM,CAAA;AAIvD,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAA,IAAI,WAAW,MAAQ,EAAA;AACrB,MAAA,OAAO,MAAM,IAAA;AAAA;AAEf,IAAM,MAAA,UAAA,GAAa,YAAY,MAAM,OAAA,qBAAY,IAAK,EAAC,GAAG,GAAI,CAAA;AAC9D,IAAO,OAAA,MAAM,cAAc,UAAU,CAAA;AAAA,GACvC,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,IAAI,WAAW,MAAQ,EAAA;AACrB,IAAO,OAAA,IAAA;AAAA;AAGT,EAAI,IAAA;AACF,IAAA,MAAM,cACJ,MAAW,KAAA,MAAA,IACX,WAAW,MACX,IAAA,MAAA,KAAW,qBACX,MAAW,KAAA,MAAA;AACb,IAAA,MAAM,cACJ,MAAW,KAAA,MAAA,IACX,WAAW,MACX,IAAA,MAAA,KAAW,qBACX,MAAW,KAAA,MAAA;AAEb,IAAA,MAAM,QACJ,MAAW,KAAA,MAAA,IAAU,WAAW,iBAC5B,GAAA,IAAA,CAAK,mBAAmB,IAAM,EAAA;AAAA,MAC5B,OAAA,EAAS,MAAW,KAAA,iBAAA,GAAoB,MAAS,GAAA,KAAA,CAAA;AAAA,MACjD,GAAK,EAAA,SAAA;AAAA,MACL,KAAO,EAAA,SAAA;AAAA,MACP,IAAM,EAAA;AAAA,KACP,CAAA,GACD,IAAK,CAAA,kBAAA,CAAmB,IAAM,EAAA;AAAA,MAC5B,OAAA,EAAS,MAAW,KAAA,MAAA,GAAS,MAAS,GAAA,KAAA,CAAA;AAAA,MACtC,GAAA,EAAK,cAAc,SAAY,GAAA,KAAA,CAAA;AAAA,MAC/B,KAAA,EAAO,cAAc,SAAY,GAAA,KAAA,CAAA;AAAA,MACjC,IAAA,EAAM,cAAc,SAAY,GAAA,KAAA,CAAA;AAAA,MAChC,IAAA,EAAM,cAAc,SAAY,GAAA,KAAA,CAAA;AAAA,MAChC,MAAA,EAAQ,cAAc,SAAY,GAAA,KAAA,CAAA;AAAA,MAClC,MAAA,EAAQ,MAAW,KAAA,iBAAA,GAAoB,SAAY,GAAA,KAAA;AAAA,KACpD,CAAA;AACP,IAAM,MAAA,QAAA,GAAW,IAAK,CAAA,kBAAA,CAAmB,IAAM,EAAA;AAAA,MAC7C,GAAK,EAAA,SAAA;AAAA,MACL,KAAO,EAAA,SAAA;AAAA,MACP,IAAM,EAAA,SAAA;AAAA,MACN,IAAM,EAAA,SAAA;AAAA,MACN,MAAQ,EAAA,SAAA;AAAA,MACR,MAAQ,EAAA;AAAA,KACT,CAAA;AAED,IACE,uBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,MAAM,KAAS,IAAA,EAAA;AAAA,QACtB,KACE,kBAAA,KAAA,CAAA,aAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,QAAA;AAAA,YACA,KAAA,EAAO,MAAM,KAAQ,GAAA,KAAK,EAAE,QAAA,EAAU,MAAQ,EAAA,UAAA,EAAY,MAAO;AAAA,WAAA;AAAA,UAEhE;AAAA;AACH;AAAA,KAEJ;AAAA,WAEK,CAAG,EAAA;AAEV,IAAQ,OAAA,CAAA,IAAA,CAAK,0BAA0B,CAAC,CAAA;AACxC,IAAO,OAAA,IAAA;AAAA;AAEX;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Markdown.esm.js","sources":["../../src/components/Markdown.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\n\nimport { MarkdownContent } from '@backstage/core-components';\n\nimport { makeStyles } from 'tss-react/mui';\n\n/**\n * @public\n */\nexport interface MarkdownProps {\n title?: string;\n content?: string;\n}\n\nconst useStyles = makeStyles()({\n // Make card content scrollable (so that cards don't overlap)\n card: {\n display: 'flex',\n flexDirection: 'column',\n width: '100%',\n height: '100%',\n },\n content: {\n overflow: 'auto',\n },\n});\n\n/**\n * @public\n */\nexport const Markdown = (props: MarkdownProps) => {\n const { classes } = useStyles();\n return (\n <div className={classes.card}>\n {props.title ? <h1>{props.title}</h1> : null}\n <MarkdownContent\n dialect=\"gfm\"\n content={props.content ?? ''}\n className={classes.content}\n />\n </div>\n );\n};\n"],"names":[],"mappings":";;;;AA6BA,MAAM,SAAA,GAAY,YAAa,CAAA;AAAA;AAAA,EAE7B,IAAM,EAAA;AAAA,IACJ,OAAS,EAAA,MAAA;AAAA,IACT,aAAe,EAAA,QAAA;AAAA,IACf,KAAO,EAAA,MAAA;AAAA,IACP,MAAQ,EAAA;AAAA,GACV;AAAA,EACA,OAAS,EAAA;AAAA,IACP,QAAU,EAAA;AAAA;AAEd,CAAC,CAAA;AAKY,MAAA,QAAA,GAAW,CAAC,KAAyB,KAAA;AAChD,EAAM,MAAA,EAAE,OAAQ,EAAA,GAAI,SAAU,EAAA;AAC9B,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,OAAA,CAAQ,IACrB,EAAA,EAAA,KAAA,CAAM,KAAQ,mBAAA,KAAA,CAAA,aAAA,CAAC,IAAI,EAAA,IAAA,EAAA,KAAA,CAAM,KAAM,CAAA,GAAQ,IACxC,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,eAAA;AAAA,IAAA;AAAA,MACC,OAAQ,EAAA,KAAA;AAAA,MACR,OAAA,EAAS,MAAM,OAAW,IAAA,EAAA;AAAA,MAC1B,WAAW,OAAQ,CAAA;AAAA;AAAA,GAEvB,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"Markdown.esm.js","sources":["../../src/components/Markdown.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 React from 'react';\n\nimport { MarkdownContent } from '@backstage/core-components';\n\nimport { makeStyles } from 'tss-react/mui';\n\n/**\n * @public\n */\nexport interface MarkdownProps {\n title?: string;\n content?: string;\n}\n\nconst useStyles = makeStyles()({\n // Make card content scrollable (so that cards don't overlap)\n card: {\n display: 'flex',\n flexDirection: 'column',\n width: '100%',\n height: '100%',\n },\n content: {\n overflow: 'auto',\n },\n});\n\n/**\n * @public\n */\nexport const Markdown = (props: MarkdownProps) => {\n const { classes } = useStyles();\n return (\n <div className={classes.card}>\n {props.title ? <h1>{props.title}</h1> : null}\n <MarkdownContent\n dialect=\"gfm\"\n content={props.content ?? ''}\n className={classes.content}\n />\n </div>\n );\n};\n"],"names":[],"mappings":";;;;AA8BA,MAAM,SAAA,GAAY,YAAa,CAAA;AAAA;AAAA,EAE7B,IAAM,EAAA;AAAA,IACJ,OAAS,EAAA,MAAA;AAAA,IACT,aAAe,EAAA,QAAA;AAAA,IACf,KAAO,EAAA,MAAA;AAAA,IACP,MAAQ,EAAA;AAAA,GACV;AAAA,EACA,OAAS,EAAA;AAAA,IACP,QAAU,EAAA;AAAA;AAEd,CAAC,CAAA;AAKY,MAAA,QAAA,GAAW,CAAC,KAAyB,KAAA;AAChD,EAAM,MAAA,EAAE,OAAQ,EAAA,GAAI,SAAU,EAAA;AAC9B,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,OAAA,CAAQ,IACrB,EAAA,EAAA,KAAA,CAAM,KAAQ,mBAAA,KAAA,CAAA,aAAA,CAAC,IAAI,EAAA,IAAA,EAAA,KAAA,CAAM,KAAM,CAAA,GAAQ,IACxC,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,eAAA;AAAA,IAAA;AAAA,MACC,OAAQ,EAAA,KAAA;AAAA,MACR,OAAA,EAAS,MAAM,OAAW,IAAA,EAAA;AAAA,MAC1B,WAAW,OAAQ,CAAA;AAAA;AAAA,GAEvB,CAAA;AAEJ;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownCard.esm.js","sources":["../../src/components/MarkdownCard.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\n\nimport { InfoCard, MarkdownContent } from '@backstage/core-components';\n\n/**\n * @public\n */\nexport interface MarkdownCardProps {\n title?: string;\n content?: string;\n}\n\n/**\n * @public\n */\nexport const MarkdownCard = (props: MarkdownCardProps) => {\n return (\n <InfoCard title={props.title}>\n <MarkdownContent dialect=\"gfm\" content={props.content ?? ''} />\n </InfoCard>\n );\n};\n"],"names":[],"mappings":";;;AA8Ba,MAAA,YAAA,GAAe,CAAC,KAA6B,KAAA;AACxD,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA,EAAS,KAAO,EAAA,KAAA,CAAM,KACrB,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,eAAgB,EAAA,EAAA,OAAA,EAAQ,KAAM,EAAA,OAAA,EAAS,KAAM,CAAA,OAAA,IAAW,IAAI,CAC/D,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"MarkdownCard.esm.js","sources":["../../src/components/MarkdownCard.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 React from 'react';\n\nimport { InfoCard, MarkdownContent } from '@backstage/core-components';\n\n/**\n * @public\n */\nexport interface MarkdownCardProps {\n title?: string;\n content?: string;\n}\n\n/**\n * @public\n */\nexport const MarkdownCard = (props: MarkdownCardProps) => {\n return (\n <InfoCard title={props.title}>\n <MarkdownContent dialect=\"gfm\" content={props.content ?? ''} />\n </InfoCard>\n );\n};\n"],"names":[],"mappings":";;;AA+Ba,MAAA,YAAA,GAAe,CAAC,KAA6B,KAAA;AACxD,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,QAAA,EAAA,EAAS,KAAO,EAAA,KAAA,CAAM,KACrB,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,eAAgB,EAAA,EAAA,OAAA,EAAQ,KAAM,EAAA,OAAA,EAAS,KAAM,CAAA,OAAA,IAAW,IAAI,CAC/D,CAAA;AAEJ;;;;"}
@@ -18,8 +18,8 @@ const useStyles = makeStyles()({
18
18
  const Placeholder = (props) => {
19
19
  const { classes } = useStyles();
20
20
  const className = [
21
- props.debugContent ? classes.centerDebugContent : void 0,
22
- props.showBorder ? classes.showBorder : void 0
21
+ props.debugContent ? classes.centerDebugContent : undefined,
22
+ props.showBorder ? classes.showBorder : undefined
23
23
  ].filter(Boolean).join(" ");
24
24
  return /* @__PURE__ */ React.createElement("div", { "data-testid": "placeholder", className }, props.debugContent);
25
25
  };
@@ -1 +1 @@
1
- {"version":3,"file":"Placeholder.esm.js","sources":["../../src/components/Placeholder.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\n\nimport { makeStyles } from 'tss-react/mui';\n\n/**\n * @public\n */\nexport interface PlaceholderProps {\n showBorder?: boolean;\n debugContent?: string;\n}\n\nconst useStyles = makeStyles()({\n centerDebugContent: {\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n // Make card content scrollable (so that cards don't overlap)\n showBorder: {\n border: '1px solid gray',\n width: '100%',\n height: '100%',\n },\n});\n\n/**\n * @public\n */\nexport const Placeholder = (props: PlaceholderProps) => {\n const { classes } = useStyles();\n const className = [\n props.debugContent ? classes.centerDebugContent : undefined,\n props.showBorder ? classes.showBorder : undefined,\n ]\n .filter(Boolean)\n .join(' ');\n return (\n <div data-testid=\"placeholder\" className={className}>\n {props.debugContent}\n </div>\n );\n};\n"],"names":[],"mappings":";;;AA2BA,MAAM,SAAA,GAAY,YAAa,CAAA;AAAA,EAC7B,kBAAoB,EAAA;AAAA,IAClB,MAAQ,EAAA,MAAA;AAAA,IACR,OAAS,EAAA,MAAA;AAAA,IACT,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA;AAAA,GAClB;AAAA;AAAA,EAEA,UAAY,EAAA;AAAA,IACV,MAAQ,EAAA,gBAAA;AAAA,IACR,KAAO,EAAA,MAAA;AAAA,IACP,MAAQ,EAAA;AAAA;AAEZ,CAAC,CAAA;AAKY,MAAA,WAAA,GAAc,CAAC,KAA4B,KAAA;AACtD,EAAM,MAAA,EAAE,OAAQ,EAAA,GAAI,SAAU,EAAA;AAC9B,EAAA,MAAM,SAAY,GAAA;AAAA,IAChB,KAAA,CAAM,YAAe,GAAA,OAAA,CAAQ,kBAAqB,GAAA,KAAA,CAAA;AAAA,IAClD,KAAA,CAAM,UAAa,GAAA,OAAA,CAAQ,UAAa,GAAA,KAAA;AAAA,GAEvC,CAAA,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AACX,EAAA,2CACG,KAAI,EAAA,EAAA,aAAA,EAAY,aAAc,EAAA,SAAA,EAAA,EAC5B,MAAM,YACT,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"Placeholder.esm.js","sources":["../../src/components/Placeholder.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 React from 'react';\n\nimport { makeStyles } from 'tss-react/mui';\n\n/**\n * @public\n */\nexport interface PlaceholderProps {\n showBorder?: boolean;\n debugContent?: string;\n}\n\nconst useStyles = makeStyles()({\n centerDebugContent: {\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n // Make card content scrollable (so that cards don't overlap)\n showBorder: {\n border: '1px solid gray',\n width: '100%',\n height: '100%',\n },\n});\n\n/**\n * @public\n */\nexport const Placeholder = (props: PlaceholderProps) => {\n const { classes } = useStyles();\n const className = [\n props.debugContent ? classes.centerDebugContent : undefined,\n props.showBorder ? classes.showBorder : undefined,\n ]\n .filter(Boolean)\n .join(' ');\n return (\n <div data-testid=\"placeholder\" className={className}>\n {props.debugContent}\n </div>\n );\n};\n"],"names":[],"mappings":";;;AA4BA,MAAM,SAAA,GAAY,YAAa,CAAA;AAAA,EAC7B,kBAAoB,EAAA;AAAA,IAClB,MAAQ,EAAA,MAAA;AAAA,IACR,OAAS,EAAA,MAAA;AAAA,IACT,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA;AAAA,GAClB;AAAA;AAAA,EAEA,UAAY,EAAA;AAAA,IACV,MAAQ,EAAA,gBAAA;AAAA,IACR,KAAO,EAAA,MAAA;AAAA,IACP,MAAQ,EAAA;AAAA;AAEZ,CAAC,CAAA;AAKY,MAAA,WAAA,GAAc,CAAC,KAA4B,KAAA;AACtD,EAAM,MAAA,EAAE,OAAQ,EAAA,GAAI,SAAU,EAAA;AAC9B,EAAA,MAAM,SAAY,GAAA;AAAA,IAChB,KAAA,CAAM,YAAe,GAAA,OAAA,CAAQ,kBAAqB,GAAA,SAAA;AAAA,IAClD,KAAA,CAAM,UAAa,GAAA,OAAA,CAAQ,UAAa,GAAA;AAAA,GAEvC,CAAA,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AACX,EAAA,2CACG,KAAI,EAAA,EAAA,aAAA,EAAY,aAAc,EAAA,SAAA,EAAA,EAC5B,MAAM,YACT,CAAA;AAEJ;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"QuickAccessCard.esm.js","sources":["../../src/components/QuickAccessCard.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\n\nimport {\n CodeSnippet,\n InfoCard,\n WarningPanel,\n} from '@backstage/core-components';\nimport { ComponentAccordion, HomePageToolkit } from '@backstage/plugin-home';\n\nimport CircularProgress from '@mui/material/CircularProgress';\nimport { makeStyles } from 'tss-react/mui';\n\nimport { useQuickAccessLinks } from '../hooks/useQuickAccessLinks';\n\nconst useStyles = makeStyles()({\n center: {\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n img: {\n height: '40px',\n width: 'auto',\n },\n title: {\n '& div > div > div > div > p': {\n textTransform: 'uppercase',\n },\n },\n});\n\n/**\n * @public\n */\nexport interface QuickAccessCardProps {\n title?: string;\n path?: string;\n}\n\n/**\n * @public\n */\nexport const QuickAccessCard = (props: QuickAccessCardProps) => {\n const { classes } = useStyles();\n const { data, error, isLoading } = useQuickAccessLinks(props.path);\n\n let content: React.ReactNode;\n\n if (isLoading) {\n content = (\n <div className={classes.center}>\n <CircularProgress />\n </div>\n );\n } else if (!data) {\n content = (\n <WarningPanel severity=\"error\" title=\"Could not fetch data.\">\n <CodeSnippet\n language=\"text\"\n text={error?.toString() ?? 'Unknown error'}\n />\n </WarningPanel>\n );\n } else {\n content = (\n <>\n {data.map(item => (\n <HomePageToolkit\n key={item.title}\n title={item.title}\n tools={item.links.map(link => ({\n ...link,\n icon: (\n <img\n className={classes.img}\n src={link.iconUrl}\n alt={link.label}\n />\n ),\n }))}\n // Component creation is allowed inside component props only\n // if prop name starts with `render`.\n // We accept it here since the upstream package use `Renderer` instead.\n Renderer={(\n renderProps, // NOSONAR\n ) => (\n <ComponentAccordion expanded={item.isExpanded} {...renderProps} />\n )}\n />\n ))}\n </>\n );\n }\n\n return (\n <InfoCard\n title={props.title ?? 'Quick Access'}\n noPadding\n className={classes.title}\n >\n {content}\n </InfoCard>\n );\n};\n"],"names":[],"mappings":";;;;;;;AA6BA,MAAM,SAAA,GAAY,YAAa,CAAA;AAAA,EAC7B,MAAQ,EAAA;AAAA,IACN,MAAQ,EAAA,MAAA;AAAA,IACR,OAAS,EAAA,MAAA;AAAA,IACT,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA;AAAA,GAClB;AAAA,EACA,GAAK,EAAA;AAAA,IACH,MAAQ,EAAA,MAAA;AAAA,IACR,KAAO,EAAA;AAAA,GACT;AAAA,EACA,KAAO,EAAA;AAAA,IACL,6BAA+B,EAAA;AAAA,MAC7B,aAAe,EAAA;AAAA;AACjB;AAEJ,CAAC,CAAA;AAaY,MAAA,eAAA,GAAkB,CAAC,KAAgC,KAAA;AAC9D,EAAM,MAAA,EAAE,OAAQ,EAAA,GAAI,SAAU,EAAA;AAC9B,EAAA,MAAM,EAAE,IAAM,EAAA,KAAA,EAAO,WAAc,GAAA,mBAAA,CAAoB,MAAM,IAAI,CAAA;AAEjE,EAAI,IAAA,OAAA;AAEJ,EAAA,IAAI,SAAW,EAAA;AACb,IAAA,OAAA,uCACG,KAAI,EAAA,EAAA,SAAA,EAAW,QAAQ,MACtB,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,sBAAiB,CACpB,CAAA;AAAA,GAEJ,MAAA,IAAW,CAAC,IAAM,EAAA;AAChB,IAAA,OAAA,mBACG,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA,EAAa,QAAS,EAAA,OAAA,EAAQ,OAAM,uBACnC,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,QAAS,EAAA,MAAA;AAAA,QACT,IAAA,EAAM,KAAO,EAAA,QAAA,EAAc,IAAA;AAAA;AAAA,KAE/B,CAAA;AAAA,GAEG,MAAA;AACL,IACE,OAAA,mBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EACG,IAAK,CAAA,GAAA,CAAI,CACR,IAAA,qBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,eAAA;AAAA,MAAA;AAAA,QACC,KAAK,IAAK,CAAA,KAAA;AAAA,QACV,OAAO,IAAK,CAAA,KAAA;AAAA,QACZ,KAAO,EAAA,IAAA,CAAK,KAAM,CAAA,GAAA,CAAI,CAAS,IAAA,MAAA;AAAA,UAC7B,GAAG,IAAA;AAAA,UACH,IACE,kBAAA,KAAA,CAAA,aAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,WAAW,OAAQ,CAAA,GAAA;AAAA,cACnB,KAAK,IAAK,CAAA,OAAA;AAAA,cACV,KAAK,IAAK,CAAA;AAAA;AAAA;AACZ,SAEF,CAAA,CAAA;AAAA,QAIF,QAAA,EAAU,CACR,WAEA,qBAAA,KAAA,CAAA,aAAA,CAAC,sBAAmB,QAAU,EAAA,IAAA,CAAK,UAAa,EAAA,GAAG,WAAa,EAAA;AAAA;AAAA,KAGrE,CACH,CAAA;AAAA;AAIJ,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,MAAM,KAAS,IAAA,cAAA;AAAA,MACtB,SAAS,EAAA,IAAA;AAAA,MACT,WAAW,OAAQ,CAAA;AAAA,KAAA;AAAA,IAElB;AAAA,GACH;AAEJ;;;;"}
1
+ {"version":3,"file":"QuickAccessCard.esm.js","sources":["../../src/components/QuickAccessCard.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 React from 'react';\n\nimport {\n CodeSnippet,\n InfoCard,\n WarningPanel,\n} from '@backstage/core-components';\nimport { ComponentAccordion, HomePageToolkit } from '@backstage/plugin-home';\n\nimport CircularProgress from '@mui/material/CircularProgress';\nimport { makeStyles } from 'tss-react/mui';\n\nimport { useQuickAccessLinks } from '../hooks/useQuickAccessLinks';\n\nconst useStyles = makeStyles()({\n center: {\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n img: {\n height: '40px',\n width: 'auto',\n },\n title: {\n '& div > div > div > div > p': {\n textTransform: 'uppercase',\n },\n },\n});\n\n/**\n * @public\n */\nexport interface QuickAccessCardProps {\n title?: string;\n path?: string;\n}\n\n/**\n * @public\n */\nexport const QuickAccessCard = (props: QuickAccessCardProps) => {\n const { classes } = useStyles();\n const { data, error, isLoading } = useQuickAccessLinks(props.path);\n\n let content: React.ReactNode;\n\n if (isLoading) {\n content = (\n <div className={classes.center}>\n <CircularProgress />\n </div>\n );\n } else if (!data) {\n content = (\n <WarningPanel severity=\"error\" title=\"Could not fetch data.\">\n <CodeSnippet\n language=\"text\"\n text={error?.toString() ?? 'Unknown error'}\n />\n </WarningPanel>\n );\n } else {\n content = (\n <>\n {data.map(item => (\n <HomePageToolkit\n key={item.title}\n title={item.title}\n tools={item.links.map(link => ({\n ...link,\n icon: (\n <img\n className={classes.img}\n src={link.iconUrl}\n alt={link.label}\n />\n ),\n }))}\n // Component creation is allowed inside component props only\n // if prop name starts with `render`.\n // We accept it here since the upstream package use `Renderer` instead.\n Renderer={(\n renderProps, // NOSONAR\n ) => (\n <ComponentAccordion expanded={item.isExpanded} {...renderProps} />\n )}\n />\n ))}\n </>\n );\n }\n\n return (\n <InfoCard\n title={props.title ?? 'Quick Access'}\n noPadding\n className={classes.title}\n >\n {content}\n </InfoCard>\n );\n};\n"],"names":[],"mappings":";;;;;;;AA8BA,MAAM,SAAA,GAAY,YAAa,CAAA;AAAA,EAC7B,MAAQ,EAAA;AAAA,IACN,MAAQ,EAAA,MAAA;AAAA,IACR,OAAS,EAAA,MAAA;AAAA,IACT,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA;AAAA,GAClB;AAAA,EACA,GAAK,EAAA;AAAA,IACH,MAAQ,EAAA,MAAA;AAAA,IACR,KAAO,EAAA;AAAA,GACT;AAAA,EACA,KAAO,EAAA;AAAA,IACL,6BAA+B,EAAA;AAAA,MAC7B,aAAe,EAAA;AAAA;AACjB;AAEJ,CAAC,CAAA;AAaY,MAAA,eAAA,GAAkB,CAAC,KAAgC,KAAA;AAC9D,EAAM,MAAA,EAAE,OAAQ,EAAA,GAAI,SAAU,EAAA;AAC9B,EAAA,MAAM,EAAE,IAAM,EAAA,KAAA,EAAO,WAAc,GAAA,mBAAA,CAAoB,MAAM,IAAI,CAAA;AAEjE,EAAI,IAAA,OAAA;AAEJ,EAAA,IAAI,SAAW,EAAA;AACb,IAAA,OAAA,uCACG,KAAI,EAAA,EAAA,SAAA,EAAW,QAAQ,MACtB,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,sBAAiB,CACpB,CAAA;AAAA,GAEJ,MAAA,IAAW,CAAC,IAAM,EAAA;AAChB,IAAA,OAAA,mBACG,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA,EAAa,QAAS,EAAA,OAAA,EAAQ,OAAM,uBACnC,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,QAAS,EAAA,MAAA;AAAA,QACT,IAAA,EAAM,KAAO,EAAA,QAAA,EAAc,IAAA;AAAA;AAAA,KAE/B,CAAA;AAAA,GAEG,MAAA;AACL,IACE,OAAA,mBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EACG,IAAK,CAAA,GAAA,CAAI,CACR,IAAA,qBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,eAAA;AAAA,MAAA;AAAA,QACC,KAAK,IAAK,CAAA,KAAA;AAAA,QACV,OAAO,IAAK,CAAA,KAAA;AAAA,QACZ,KAAO,EAAA,IAAA,CAAK,KAAM,CAAA,GAAA,CAAI,CAAS,IAAA,MAAA;AAAA,UAC7B,GAAG,IAAA;AAAA,UACH,IACE,kBAAA,KAAA,CAAA,aAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,WAAW,OAAQ,CAAA,GAAA;AAAA,cACnB,KAAK,IAAK,CAAA,OAAA;AAAA,cACV,KAAK,IAAK,CAAA;AAAA;AAAA;AACZ,SAEF,CAAA,CAAA;AAAA,QAIF,QAAA,EAAU,CACR,WAEA,qBAAA,KAAA,CAAA,aAAA,CAAC,sBAAmB,QAAU,EAAA,IAAA,CAAK,UAAa,EAAA,GAAG,WAAa,EAAA;AAAA;AAAA,KAGrE,CACH,CAAA;AAAA;AAIJ,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,MAAM,KAAS,IAAA,cAAA;AAAA,MACtB,SAAS,EAAA,IAAA;AAAA,MACT,WAAW,OAAQ,CAAA;AAAA,KAAA;AAAA,IAElB;AAAA,GACH;AAEJ;;;;"}
@@ -114,7 +114,7 @@ const ReadOnlyGrid = (props) => {
114
114
  /* @__PURE__ */ React.createElement(ErrorBoundary, null, /* @__PURE__ */ React.createElement(card.Component, { ...card.props }))
115
115
  ));
116
116
  }, [cards, classes.cardWrapper]);
117
- return /* @__PURE__ */ React.createElement("div", { style: { margin: -gridGap } }, /* @__PURE__ */ React.createElement("div", { ref: measureRef }), measureRect.width ? /* @__PURE__ */ React.createElement(
117
+ return /* @__PURE__ */ React.createElement("div", { style: { margin: -16 } }, /* @__PURE__ */ React.createElement("div", { ref: measureRef }), measureRect.width ? /* @__PURE__ */ React.createElement(
118
118
  Responsive,
119
119
  {
120
120
  ...defaultProps,
@@ -1 +1 @@
1
- {"version":3,"file":"ReadOnlyGrid.esm.js","sources":["../../src/components/ReadOnlyGrid.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\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 React, { 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\n// Removes the doubled scrollbar\nimport 'react-grid-layout/css/styles.css';\n\nimport useMeasure from 'react-use/lib/useMeasure';\n\nimport { HomePageCardMountPoint } from '../types';\n\ninterface Card {\n id: string;\n Component: React.ComponentType<any>;\n props?: Record<string, any>;\n layouts: Record<string, Layout>;\n}\n\nconst gridGap = 16;\n\nconst defaultProps: ResponsiveProps = {\n // Aligned with the 1.0-1.2 home page gap.\n margin: [gridGap, gridGap],\n // Same as in home-plugin CustomHomepageGrid\n rowHeight: 60,\n\n // We use always a 12-column grid, but each cards can define\n // their number of columns (width) and start column (x) per breakpoint.\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 // Make card content scrollable (so that cards don't overlap)\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\n/**\n * @public\n */\nexport interface ReadOnlyGridProps {\n mountPoints: HomePageCardMountPoint[];\n breakpoints?: Record<string, number>;\n cols?: Record<string, number>;\n}\n\n/**\n * @public\n */\nexport const ReadOnlyGrid = (props: ReadOnlyGridProps) => {\n const { classes } = useStyles();\n const [measureRef, measureRect] = useMeasure<HTMLDivElement>();\n\n const cards = useMemo<Card[]>(() => {\n return props.mountPoints.map<Card>((mountPoint, index) => {\n const id = (index + 1).toString();\n const layouts: Record<string, Layout> = {};\n\n if (mountPoint.config?.layouts) {\n for (const [breakpoint, layout] of Object.entries(\n mountPoint.config.layouts,\n )) {\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 // Default layout for cards without a layout configuration\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: mountPoint.config?.props,\n layouts,\n };\n });\n }, [props.mountPoints]);\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
+ {"version":3,"file":"ReadOnlyGrid.esm.js","sources":["../../src/components/ReadOnlyGrid.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 React, { 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\n// Removes the doubled scrollbar\nimport 'react-grid-layout/css/styles.css';\n\nimport useMeasure from 'react-use/lib/useMeasure';\n\nimport { HomePageCardMountPoint } from '../types';\n\ninterface Card {\n id: string;\n Component: React.ComponentType<any>;\n props?: Record<string, any>;\n layouts: Record<string, Layout>;\n}\n\nconst gridGap = 16;\n\nconst defaultProps: ResponsiveProps = {\n // Aligned with the 1.0-1.2 home page gap.\n margin: [gridGap, gridGap],\n // Same as in home-plugin CustomHomepageGrid\n rowHeight: 60,\n\n // We use always a 12-column grid, but each cards can define\n // their number of columns (width) and start column (x) per breakpoint.\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 // Make card content scrollable (so that cards don't overlap)\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\n/**\n * @public\n */\nexport interface ReadOnlyGridProps {\n mountPoints: HomePageCardMountPoint[];\n breakpoints?: Record<string, number>;\n cols?: Record<string, number>;\n}\n\n/**\n * @public\n */\nexport const ReadOnlyGrid = (props: ReadOnlyGridProps) => {\n const { classes } = useStyles();\n const [measureRef, measureRect] = useMeasure<HTMLDivElement>();\n\n const cards = useMemo<Card[]>(() => {\n return props.mountPoints.map<Card>((mountPoint, index) => {\n const id = (index + 1).toString();\n const layouts: Record<string, Layout> = {};\n\n if (mountPoint.config?.layouts) {\n for (const [breakpoint, layout] of Object.entries(\n mountPoint.config.layouts,\n )) {\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 // Default layout for cards without a layout configuration\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: mountPoint.config?.props,\n layouts,\n };\n });\n }, [props.mountPoints]);\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 +1 @@
1
- {"version":3,"file":"SearchBar.esm.js","sources":["../../src/components/SearchBar.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, { useCallback, useRef, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\n\nimport { SearchBarBase } from '@backstage/plugin-search-react';\n\nimport { makeStyles } from 'tss-react/mui';\n\nconst useStyles = makeStyles()(theme => ({\n searchBar: {\n '&&': {\n backgroundColor: theme.palette.mode === 'dark' ? '#36373A' : '#FFFFFF',\n boxShadow: 'none',\n border: `1px solid ${\n theme.palette.mode === 'dark' ? '#57585a' : '#E4E4E4'\n }`,\n borderRadius: '50px',\n margin: 0,\n },\n },\n notchedOutline: {\n '&&': {\n borderStyle: 'none',\n },\n },\n}));\n\n/**\n * @public\n */\nexport interface SearchBarProps {\n path?: string;\n queryParam?: string;\n}\n\n/**\n * @public\n */\nexport const SearchBar = ({ path, queryParam }: SearchBarProps) => {\n const { classes } = useStyles();\n const [value, setValue] = useState('');\n const ref = useRef<HTMLInputElement | null>(null);\n const navigate = useNavigate();\n\n // This handler is called when \"enter\" is pressed\n const handleSubmit = useCallback(() => {\n const query = ref.current?.value ?? '';\n\n const url = new URL(window.location.toString());\n url.pathname = path ?? '/search';\n url.searchParams.set(queryParam ?? 'query', query);\n const search = url.searchParams.toString();\n\n navigate(`${url.pathname}${search ? '?' : ''}${search}`);\n }, [navigate, path, queryParam]);\n\n return (\n <SearchBarBase\n placeholder=\"Search\"\n value={value}\n onChange={setValue}\n onSubmit={handleSubmit}\n inputProps={{ ref }}\n classes={{\n root: classes.searchBar,\n }}\n InputProps={{\n classes: {\n notchedOutline: classes.notchedOutline,\n },\n }}\n />\n );\n};\n"],"names":[],"mappings":";;;;;AAsBA,MAAM,SAAA,GAAY,UAAW,EAAA,CAAE,CAAU,KAAA,MAAA;AAAA,EACvC,SAAW,EAAA;AAAA,IACT,IAAM,EAAA;AAAA,MACJ,eAAiB,EAAA,KAAA,CAAM,OAAQ,CAAA,IAAA,KAAS,SAAS,SAAY,GAAA,SAAA;AAAA,MAC7D,SAAW,EAAA,MAAA;AAAA,MACX,QAAQ,CACN,UAAA,EAAA,KAAA,CAAM,QAAQ,IAAS,KAAA,MAAA,GAAS,YAAY,SAC9C,CAAA,CAAA;AAAA,MACA,YAAc,EAAA,MAAA;AAAA,MACd,MAAQ,EAAA;AAAA;AACV,GACF;AAAA,EACA,cAAgB,EAAA;AAAA,IACd,IAAM,EAAA;AAAA,MACJ,WAAa,EAAA;AAAA;AACf;AAEJ,CAAE,CAAA,CAAA;AAaK,MAAM,SAAY,GAAA,CAAC,EAAE,IAAA,EAAM,YAAiC,KAAA;AACjE,EAAM,MAAA,EAAE,OAAQ,EAAA,GAAI,SAAU,EAAA;AAC9B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,EAAE,CAAA;AACrC,EAAM,MAAA,GAAA,GAAM,OAAgC,IAAI,CAAA;AAChD,EAAA,MAAM,WAAW,WAAY,EAAA;AAG7B,EAAM,MAAA,YAAA,GAAe,YAAY,MAAM;AACrC,IAAM,MAAA,KAAA,GAAQ,GAAI,CAAA,OAAA,EAAS,KAAS,IAAA,EAAA;AAEpC,IAAA,MAAM,MAAM,IAAI,GAAA,CAAI,MAAO,CAAA,QAAA,CAAS,UAAU,CAAA;AAC9C,IAAA,GAAA,CAAI,WAAW,IAAQ,IAAA,SAAA;AACvB,IAAA,GAAA,CAAI,YAAa,CAAA,GAAA,CAAI,UAAc,IAAA,OAAA,EAAS,KAAK,CAAA;AACjD,IAAM,MAAA,MAAA,GAAS,GAAI,CAAA,YAAA,CAAa,QAAS,EAAA;AAEzC,IAAS,QAAA,CAAA,CAAA,EAAG,IAAI,QAAQ,CAAA,EAAG,SAAS,GAAM,GAAA,EAAE,CAAG,EAAA,MAAM,CAAE,CAAA,CAAA;AAAA,GACtD,EAAA,CAAC,QAAU,EAAA,IAAA,EAAM,UAAU,CAAC,CAAA;AAE/B,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,WAAY,EAAA,QAAA;AAAA,MACZ,KAAA;AAAA,MACA,QAAU,EAAA,QAAA;AAAA,MACV,QAAU,EAAA,YAAA;AAAA,MACV,UAAA,EAAY,EAAE,GAAI,EAAA;AAAA,MAClB,OAAS,EAAA;AAAA,QACP,MAAM,OAAQ,CAAA;AAAA,OAChB;AAAA,MACA,UAAY,EAAA;AAAA,QACV,OAAS,EAAA;AAAA,UACP,gBAAgB,OAAQ,CAAA;AAAA;AAC1B;AACF;AAAA,GACF;AAEJ;;;;"}
1
+ {"version":3,"file":"SearchBar.esm.js","sources":["../../src/components/SearchBar.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 React, { useCallback, useRef, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\n\nimport { SearchBarBase } from '@backstage/plugin-search-react';\n\nimport { makeStyles } from 'tss-react/mui';\n\nconst useStyles = makeStyles()(theme => ({\n searchBar: {\n '&&': {\n backgroundColor: theme.palette.mode === 'dark' ? '#36373A' : '#FFFFFF',\n boxShadow: 'none',\n border: `1px solid ${\n theme.palette.mode === 'dark' ? '#57585a' : '#E4E4E4'\n }`,\n borderRadius: '50px',\n margin: 0,\n },\n },\n notchedOutline: {\n '&&': {\n borderStyle: 'none',\n },\n },\n}));\n\n/**\n * @public\n */\nexport interface SearchBarProps {\n path?: string;\n queryParam?: string;\n}\n\n/**\n * @public\n */\nexport const SearchBar = ({ path, queryParam }: SearchBarProps) => {\n const { classes } = useStyles();\n const [value, setValue] = useState('');\n const ref = useRef<HTMLInputElement | null>(null);\n const navigate = useNavigate();\n\n // This handler is called when \"enter\" is pressed\n const handleSubmit = useCallback(() => {\n const query = ref.current?.value ?? '';\n\n const url = new URL(window.location.toString());\n url.pathname = path ?? '/search';\n url.searchParams.set(queryParam ?? 'query', query);\n const search = url.searchParams.toString();\n\n navigate(`${url.pathname}${search ? '?' : ''}${search}`);\n }, [navigate, path, queryParam]);\n\n return (\n <SearchBarBase\n placeholder=\"Search\"\n value={value}\n onChange={setValue}\n onSubmit={handleSubmit}\n inputProps={{ ref }}\n classes={{\n root: classes.searchBar,\n }}\n InputProps={{\n classes: {\n notchedOutline: classes.notchedOutline,\n },\n }}\n />\n );\n};\n"],"names":[],"mappings":";;;;;AAuBA,MAAM,SAAA,GAAY,UAAW,EAAA,CAAE,CAAU,KAAA,MAAA;AAAA,EACvC,SAAW,EAAA;AAAA,IACT,IAAM,EAAA;AAAA,MACJ,eAAiB,EAAA,KAAA,CAAM,OAAQ,CAAA,IAAA,KAAS,SAAS,SAAY,GAAA,SAAA;AAAA,MAC7D,SAAW,EAAA,MAAA;AAAA,MACX,QAAQ,CACN,UAAA,EAAA,KAAA,CAAM,QAAQ,IAAS,KAAA,MAAA,GAAS,YAAY,SAC9C,CAAA,CAAA;AAAA,MACA,YAAc,EAAA,MAAA;AAAA,MACd,MAAQ,EAAA;AAAA;AACV,GACF;AAAA,EACA,cAAgB,EAAA;AAAA,IACd,IAAM,EAAA;AAAA,MACJ,WAAa,EAAA;AAAA;AACf;AAEJ,CAAE,CAAA,CAAA;AAaK,MAAM,SAAY,GAAA,CAAC,EAAE,IAAA,EAAM,YAAiC,KAAA;AACjE,EAAM,MAAA,EAAE,OAAQ,EAAA,GAAI,SAAU,EAAA;AAC9B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,EAAE,CAAA;AACrC,EAAM,MAAA,GAAA,GAAM,OAAgC,IAAI,CAAA;AAChD,EAAA,MAAM,WAAW,WAAY,EAAA;AAG7B,EAAM,MAAA,YAAA,GAAe,YAAY,MAAM;AACrC,IAAM,MAAA,KAAA,GAAQ,GAAI,CAAA,OAAA,EAAS,KAAS,IAAA,EAAA;AAEpC,IAAA,MAAM,MAAM,IAAI,GAAA,CAAI,MAAO,CAAA,QAAA,CAAS,UAAU,CAAA;AAC9C,IAAA,GAAA,CAAI,WAAW,IAAQ,IAAA,SAAA;AACvB,IAAA,GAAA,CAAI,YAAa,CAAA,GAAA,CAAI,UAAc,IAAA,OAAA,EAAS,KAAK,CAAA;AACjD,IAAM,MAAA,MAAA,GAAS,GAAI,CAAA,YAAA,CAAa,QAAS,EAAA;AAEzC,IAAS,QAAA,CAAA,CAAA,EAAG,IAAI,QAAQ,CAAA,EAAG,SAAS,GAAM,GAAA,EAAE,CAAG,EAAA,MAAM,CAAE,CAAA,CAAA;AAAA,GACtD,EAAA,CAAC,QAAU,EAAA,IAAA,EAAM,UAAU,CAAC,CAAA;AAE/B,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,WAAY,EAAA,QAAA;AAAA,MACZ,KAAA;AAAA,MACA,QAAU,EAAA,QAAA;AAAA,MACV,QAAU,EAAA,YAAA;AAAA,MACV,UAAA,EAAY,EAAE,GAAI,EAAA;AAAA,MAClB,OAAS,EAAA;AAAA,QACP,MAAM,OAAQ,CAAA;AAAA,OAChB;AAAA,MACA,UAAY,EAAA;AAAA,QACV,OAAS,EAAA;AAAA,UACP,gBAAgB,OAAQ,CAAA;AAAA;AAC1B;AACF;AAAA,GACF;AAEJ;;;;"}
@@ -1,21 +1,21 @@
1
1
  import React from 'react';
2
2
  import { VisitListener as VisitListener$1 } from '@backstage/plugin-home';
3
- import { useHomePageMountPoints } from '../hooks/useHomePageMountPoints.esm.js';
3
+ import { useDynamicHomePageCards } from '../hooks/useDynamicHomePageCards.esm.js';
4
4
 
5
5
  const VisitListener = () => {
6
- const allHomePageMountPoints = useHomePageMountPoints();
6
+ const cards = useDynamicHomePageCards();
7
7
  const shouldLoadVisitListener = React.useMemo(() => {
8
- if (!allHomePageMountPoints) {
8
+ if (!cards) {
9
9
  return false;
10
10
  }
11
11
  const requiresVisitListener = [
12
12
  "Extension(RecentlyVisitedCard)",
13
13
  "Extension(TopVisitedCard)"
14
14
  ];
15
- return allHomePageMountPoints.some(
15
+ return cards.some(
16
16
  (card) => requiresVisitListener.includes(card.Component.displayName)
17
17
  );
18
- }, [allHomePageMountPoints]);
18
+ }, [cards]);
19
19
  return shouldLoadVisitListener ? /* @__PURE__ */ React.createElement(VisitListener$1, null) : null;
20
20
  };
21
21
 
@@ -1 +1 @@
1
- {"version":3,"file":"VisitListener.esm.js","sources":["../../src/components/VisitListener.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\n\nimport { VisitListener as VisitListenerComponent } from '@backstage/plugin-home';\nimport { useHomePageMountPoints } from '../hooks/useHomePageMountPoints';\n\nexport const VisitListener = () => {\n const allHomePageMountPoints = useHomePageMountPoints();\n\n const shouldLoadVisitListener = React.useMemo<boolean>(() => {\n if (!allHomePageMountPoints) {\n return false;\n }\n\n const requiresVisitListener = [\n 'Extension(RecentlyVisitedCard)',\n 'Extension(TopVisitedCard)',\n ];\n\n return allHomePageMountPoints.some(card =>\n requiresVisitListener.includes(card.Component.displayName!),\n );\n }, [allHomePageMountPoints]);\n\n return shouldLoadVisitListener ? <VisitListenerComponent /> : null;\n};\n"],"names":["VisitListenerComponent"],"mappings":";;;;AAoBO,MAAM,gBAAgB,MAAM;AACjC,EAAA,MAAM,yBAAyB,sBAAuB,EAAA;AAEtD,EAAM,MAAA,uBAAA,GAA0B,KAAM,CAAA,OAAA,CAAiB,MAAM;AAC3D,IAAA,IAAI,CAAC,sBAAwB,EAAA;AAC3B,MAAO,OAAA,KAAA;AAAA;AAGT,IAAA,MAAM,qBAAwB,GAAA;AAAA,MAC5B,gCAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,OAAO,sBAAuB,CAAA,IAAA;AAAA,MAAK,CACjC,IAAA,KAAA,qBAAA,CAAsB,QAAS,CAAA,IAAA,CAAK,UAAU,WAAY;AAAA,KAC5D;AAAA,GACF,EAAG,CAAC,sBAAsB,CAAC,CAAA;AAE3B,EAAO,OAAA,uBAAA,mBAA2B,KAAA,CAAA,aAAA,CAAAA,eAAA,EAAA,IAAuB,CAAK,GAAA,IAAA;AAChE;;;;"}
1
+ {"version":3,"file":"VisitListener.esm.js","sources":["../../src/components/VisitListener.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 React from 'react';\n\nimport { VisitListener as VisitListenerComponent } from '@backstage/plugin-home';\nimport { useDynamicHomePageCards } from '../hooks/useDynamicHomePageCards';\n\nexport const VisitListener = () => {\n const cards = useDynamicHomePageCards();\n\n const shouldLoadVisitListener = React.useMemo<boolean>(() => {\n if (!cards) {\n return false;\n }\n\n const requiresVisitListener = [\n 'Extension(RecentlyVisitedCard)',\n 'Extension(TopVisitedCard)',\n ];\n\n return cards.some(card =>\n requiresVisitListener.includes(card.Component.displayName!),\n );\n }, [cards]);\n\n return shouldLoadVisitListener ? <VisitListenerComponent /> : null;\n};\n"],"names":["VisitListenerComponent"],"mappings":";;;;AAqBO,MAAM,gBAAgB,MAAM;AACjC,EAAA,MAAM,QAAQ,uBAAwB,EAAA;AAEtC,EAAM,MAAA,uBAAA,GAA0B,KAAM,CAAA,OAAA,CAAiB,MAAM;AAC3D,IAAA,IAAI,CAAC,KAAO,EAAA;AACV,MAAO,OAAA,KAAA;AAAA;AAGT,IAAA,MAAM,qBAAwB,GAAA;AAAA,MAC5B,gCAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,OAAO,KAAM,CAAA,IAAA;AAAA,MAAK,CAChB,IAAA,KAAA,qBAAA,CAAsB,QAAS,CAAA,IAAA,CAAK,UAAU,WAAY;AAAA,KAC5D;AAAA,GACF,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAO,OAAA,uBAAA,mBAA2B,KAAA,CAAA,aAAA,CAAAA,eAAA,EAAA,IAAuB,CAAK,GAAA,IAAA;AAChE;;;;"}
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { HeaderWorldClock } from '@backstage/plugin-home';
3
+
4
+ const WorldClock = ({
5
+ worldClocks,
6
+ timeFormat,
7
+ justifyContent = "space-between"
8
+ }) => {
9
+ return /* @__PURE__ */ React.createElement("div", { style: { display: "flex", justifyContent } }, /* @__PURE__ */ React.createElement(
10
+ HeaderWorldClock,
11
+ {
12
+ clockConfigs: worldClocks,
13
+ customTimeFormat: timeFormat
14
+ }
15
+ ));
16
+ };
17
+
18
+ export { WorldClock };
19
+ //# sourceMappingURL=WorldClock.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorldClock.esm.js","sources":["../../src/components/WorldClock.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 React from 'react';\n\nimport { ClockConfig, HeaderWorldClock } from '@backstage/plugin-home';\n\n/**\n * @public\n */\nexport interface WorldClockProps {\n worldClocks: ClockConfig[];\n timeFormat?: Intl.DateTimeFormatOptions;\n justifyContent?: 'space-between' | 'space-around';\n}\n\n/**\n * @public\n */\nexport const WorldClock = ({\n worldClocks,\n timeFormat,\n justifyContent = 'space-between',\n}: WorldClockProps) => {\n return (\n <div style={{ display: 'flex', justifyContent }}>\n <HeaderWorldClock\n clockConfigs={worldClocks}\n customTimeFormat={timeFormat}\n />\n </div>\n );\n};\n"],"names":[],"mappings":";;;AAgCO,MAAM,aAAa,CAAC;AAAA,EACzB,WAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAiB,GAAA;AACnB,CAAuB,KAAA;AACrB,EAAA,2CACG,KAAI,EAAA,EAAA,KAAA,EAAO,EAAE,OAAS,EAAA,MAAA,EAAQ,gBAC7B,EAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,gBAAA;AAAA,IAAA;AAAA,MACC,YAAc,EAAA,WAAA;AAAA,MACd,gBAAkB,EAAA;AAAA;AAAA,GAEtB,CAAA;AAEJ;;;;"}
@@ -0,0 +1,10 @@
1
+ import { useScalprum } from '@scalprum/react-core';
2
+
3
+ const useDynamicHomePageCards = () => {
4
+ const scalprum = useScalprum();
5
+ const cards = scalprum?.api?.dynamicRootConfig?.mountPoints?.["home.page/cards"];
6
+ return cards;
7
+ };
8
+
9
+ export { useDynamicHomePageCards };
10
+ //# sourceMappingURL=useDynamicHomePageCards.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDynamicHomePageCards.esm.js","sources":["../../src/hooks/useDynamicHomePageCards.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 { useScalprum } from '@scalprum/react-core';\n\nimport { HomePageCardMountPoint } from '../types';\n\ninterface ScalprumState {\n api?: {\n dynamicRootConfig?: {\n mountPoints?: {\n 'home.page/cards': HomePageCardMountPoint[];\n };\n };\n };\n}\n\nexport const useDynamicHomePageCards = ():\n | HomePageCardMountPoint[]\n | undefined => {\n const scalprum = useScalprum<ScalprumState>();\n\n const cards =\n scalprum?.api?.dynamicRootConfig?.mountPoints?.['home.page/cards'];\n\n return cards;\n};\n"],"names":[],"mappings":";;AA8BO,MAAM,0BAA0B,MAEtB;AACf,EAAA,MAAM,WAAW,WAA2B,EAAA;AAE5C,EAAA,MAAM,KACJ,GAAA,QAAA,EAAU,GAAK,EAAA,iBAAA,EAAmB,cAAc,iBAAiB,CAAA;AAEnE,EAAO,OAAA,KAAA;AACT;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useQuickAccessLinks.esm.js","sources":["../../src/hooks/useQuickAccessLinks.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useCallback, useEffect, useState } from 'react';\nimport useAsync from 'react-use/lib/useAsync';\n\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport { quickAccessApiRef } from '../api/QuickAccessApiClient';\nimport { QuickAccessLink } from '../types';\n\nexport const useQuickAccessLinks = (\n path?: string,\n): {\n data: QuickAccessLink[] | undefined;\n error: Error | undefined;\n isLoading: boolean;\n} => {\n const [isLoading, setIsLoading] = useState<boolean>(true);\n const [data, setData] = useState<QuickAccessLink[]>();\n const [error, setError] = useState<Error>();\n const client = useApi(quickAccessApiRef);\n const {\n value,\n error: apiError,\n loading,\n } = useAsync(() => {\n return client.getQuickAccessLinks(path);\n });\n\n const fetchData = useCallback(async () => {\n const res = await fetch('/homepage/data.json');\n const qsData = await res.json();\n setData(qsData);\n setIsLoading(false);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n if (apiError) {\n setError(apiError);\n fetchData().catch(err => {\n setError(err);\n setIsLoading(false);\n });\n } else if (!loading && value) {\n setData(value);\n setIsLoading(false);\n }\n }, [apiError, fetchData, loading, setData, value]);\n\n return { data, error, isLoading };\n};\n"],"names":[],"mappings":";;;;;AAuBa,MAAA,mBAAA,GAAsB,CACjC,IAKG,KAAA;AACH,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAkB,IAAI,CAAA;AACxD,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,QAA4B,EAAA;AACpD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,QAAgB,EAAA;AAC1C,EAAM,MAAA,MAAA,GAAS,OAAO,iBAAiB,CAAA;AACvC,EAAM,MAAA;AAAA,IACJ,KAAA;AAAA,IACA,KAAO,EAAA,QAAA;AAAA,IACP;AAAA,GACF,GAAI,SAAS,MAAM;AACjB,IAAO,OAAA,MAAA,CAAO,oBAAoB,IAAI,CAAA;AAAA,GACvC,CAAA;AAED,EAAM,MAAA,SAAA,GAAY,YAAY,YAAY;AACxC,IAAM,MAAA,GAAA,GAAM,MAAM,KAAA,CAAM,qBAAqB,CAAA;AAC7C,IAAM,MAAA,MAAA,GAAS,MAAM,GAAA,CAAI,IAAK,EAAA;AAC9B,IAAA,OAAA,CAAQ,MAAM,CAAA;AACd,IAAA,YAAA,CAAa,KAAK,CAAA;AAAA,GAEpB,EAAG,EAAE,CAAA;AAEL,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,QAAU,EAAA;AACZ,MAAA,QAAA,CAAS,QAAQ,CAAA;AACjB,MAAU,SAAA,EAAA,CAAE,MAAM,CAAO,GAAA,KAAA;AACvB,QAAA,QAAA,CAAS,GAAG,CAAA;AACZ,QAAA,YAAA,CAAa,KAAK,CAAA;AAAA,OACnB,CAAA;AAAA,KACH,MAAA,IAAW,CAAC,OAAA,IAAW,KAAO,EAAA;AAC5B,MAAA,OAAA,CAAQ,KAAK,CAAA;AACb,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA;AACpB,KACC,CAAC,QAAA,EAAU,WAAW,OAAS,EAAA,OAAA,EAAS,KAAK,CAAC,CAAA;AAEjD,EAAO,OAAA,EAAE,IAAM,EAAA,KAAA,EAAO,SAAU,EAAA;AAClC;;;;"}
1
+ {"version":3,"file":"useQuickAccessLinks.esm.js","sources":["../../src/hooks/useQuickAccessLinks.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 { useCallback, useEffect, useState } from 'react';\nimport useAsync from 'react-use/lib/useAsync';\n\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport { quickAccessApiRef } from '../api/QuickAccessApiClient';\nimport { QuickAccessLink } from '../types';\n\nexport const useQuickAccessLinks = (\n path?: string,\n): {\n data: QuickAccessLink[] | undefined;\n error: Error | undefined;\n isLoading: boolean;\n} => {\n const [isLoading, setIsLoading] = useState<boolean>(true);\n const [data, setData] = useState<QuickAccessLink[]>();\n const [error, setError] = useState<Error>();\n const client = useApi(quickAccessApiRef);\n const {\n value,\n error: apiError,\n loading,\n } = useAsync(() => {\n return client.getQuickAccessLinks(path);\n });\n\n const fetchData = useCallback(async () => {\n const res = await fetch('/homepage/data.json');\n const qsData = await res.json();\n setData(qsData);\n setIsLoading(false);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n if (apiError) {\n setError(apiError);\n fetchData().catch(err => {\n setError(err);\n setIsLoading(false);\n });\n } else if (!loading && value) {\n setData(value);\n setIsLoading(false);\n }\n }, [apiError, fetchData, loading, setData, value]);\n\n return { data, error, isLoading };\n};\n"],"names":[],"mappings":";;;;;AAwBa,MAAA,mBAAA,GAAsB,CACjC,IAKG,KAAA;AACH,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAkB,IAAI,CAAA;AACxD,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,QAA4B,EAAA;AACpD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,QAAgB,EAAA;AAC1C,EAAM,MAAA,MAAA,GAAS,OAAO,iBAAiB,CAAA;AACvC,EAAM,MAAA;AAAA,IACJ,KAAA;AAAA,IACA,KAAO,EAAA,QAAA;AAAA,IACP;AAAA,GACF,GAAI,SAAS,MAAM;AACjB,IAAO,OAAA,MAAA,CAAO,oBAAoB,IAAI,CAAA;AAAA,GACvC,CAAA;AAED,EAAM,MAAA,SAAA,GAAY,YAAY,YAAY;AACxC,IAAM,MAAA,GAAA,GAAM,MAAM,KAAA,CAAM,qBAAqB,CAAA;AAC7C,IAAM,MAAA,MAAA,GAAS,MAAM,GAAA,CAAI,IAAK,EAAA;AAC9B,IAAA,OAAA,CAAQ,MAAM,CAAA;AACd,IAAA,YAAA,CAAa,KAAK,CAAA;AAAA,GAEpB,EAAG,EAAE,CAAA;AAEL,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,QAAU,EAAA;AACZ,MAAA,QAAA,CAAS,QAAQ,CAAA;AACjB,MAAU,SAAA,EAAA,CAAE,MAAM,CAAO,GAAA,KAAA;AACvB,QAAA,QAAA,CAAS,GAAG,CAAA;AACZ,QAAA,YAAA,CAAa,KAAK,CAAA;AAAA,OACnB,CAAA;AAAA,KACH,MAAA,IAAW,CAAC,OAAA,IAAW,KAAO,EAAA;AAC5B,MAAA,OAAA,CAAQ,KAAK,CAAA;AACb,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA;AACpB,KACC,CAAC,QAAA,EAAU,WAAW,OAAS,EAAA,OAAA,EAAS,KAAK,CAAC,CAAA;AAEjD,EAAO,OAAA,EAAE,IAAM,EAAA,KAAA,EAAO,SAAU,EAAA;AAClC;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,12 +1,51 @@
1
+ import { ClockConfig, StarredEntitiesProps, VisitedByTypeProps, FeaturedDocsCardProps } from '@backstage/plugin-home';
1
2
  import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
2
3
  import React from 'react';
3
- import { StarredEntitiesProps, VisitedByTypeProps, FeaturedDocsCardProps } from '@backstage/plugin-home';
4
4
 
5
5
  /**
6
6
  * @public
7
7
  */
8
+ interface WorldClockProps {
9
+ worldClocks: ClockConfig[];
10
+ timeFormat?: Intl.DateTimeFormatOptions;
11
+ justifyContent?: 'space-between' | 'space-around';
12
+ }
13
+
14
+ /**
15
+ * @public
16
+ */
17
+ interface LocalClockProps {
18
+ label?: string;
19
+ format?: 'none' | 'full' | 'date' | 'datewithweekday' | 'time' | 'timewithseconds' | 'both';
20
+ lang?: string;
21
+ }
22
+
23
+ /**
24
+ * This type is similar to Omit&lt;HomePageProps, 'cards'&gt;.
25
+ * We redefine it here to avoid the need to export HomePageProps to the API export!
26
+ * @public
27
+ */
8
28
  interface DynamicHomePageProps {
9
29
  title?: string;
30
+ personalizedTitle?: string;
31
+ pageTitle?: string;
32
+ subtitle?: string;
33
+ localClock?: LocalClockProps;
34
+ worldClocks?: ClockConfig[];
35
+ }
36
+
37
+ /**
38
+ * This type is similar to Omit&lt;HomePageProps, 'cards'&gt;.
39
+ * We redefine it here to avoid the need to export HomePageProps to the API export!
40
+ * @public
41
+ */
42
+ interface DynamicCustomizableHomePageProps {
43
+ title?: string;
44
+ personalizedTitle?: string;
45
+ pageTitle?: string;
46
+ subtitle?: string;
47
+ localClock?: LocalClockProps;
48
+ worldClocks?: ClockConfig[];
10
49
  }
11
50
 
12
51
  /**
@@ -69,6 +108,11 @@ declare const dynamicHomePagePlugin: _backstage_core_plugin_api.BackstagePlugin<
69
108
  * @public
70
109
  */
71
110
  declare const DynamicHomePage: React.ComponentType<DynamicHomePageProps>;
111
+ /**
112
+ * Customizable Dynamic Home Page
113
+ * @public
114
+ */
115
+ declare const DynamicCustomizableHomePage: React.ComponentType<DynamicCustomizableHomePageProps>;
72
116
  /**
73
117
  * @public
74
118
  */
@@ -119,5 +163,9 @@ declare const JokeCard: React.ComponentType<{
119
163
  * @public
120
164
  */
121
165
  declare const VisitListener: () => React.JSX.Element | null;
166
+ /**
167
+ * @public
168
+ */
169
+ declare const WorldClock: ({ worldClocks, timeFormat, justifyContent, }: WorldClockProps) => React.JSX.Element;
122
170
 
123
- export { CatalogStarredEntitiesCard, DynamicHomePage, type DynamicHomePageProps, FeaturedDocsCard, Headline, type HeadlineProps, JokeCard, Markdown, MarkdownCard, type MarkdownCardProps, type MarkdownProps, Placeholder, type PlaceholderProps, QuickAccessCard, type QuickAccessCardProps, RecentlyVisitedCard, SearchBar, type SearchBarProps, TopVisitedCard, VisitListener, dynamicHomePagePlugin };
171
+ export { CatalogStarredEntitiesCard, DynamicCustomizableHomePage, type DynamicCustomizableHomePageProps, DynamicHomePage, type DynamicHomePageProps, FeaturedDocsCard, Headline, type HeadlineProps, JokeCard, type LocalClockProps, Markdown, MarkdownCard, type MarkdownCardProps, type MarkdownProps, Placeholder, type PlaceholderProps, QuickAccessCard, type QuickAccessCardProps, RecentlyVisitedCard, SearchBar, type SearchBarProps, TopVisitedCard, VisitListener, WorldClock, type WorldClockProps, dynamicHomePagePlugin };
package/dist/index.esm.js CHANGED
@@ -1,2 +1,2 @@
1
- export { CatalogStarredEntitiesCard, DynamicHomePage, FeaturedDocsCard, Headline, JokeCard, Markdown, MarkdownCard, Placeholder, QuickAccessCard, RecentlyVisitedCard, SearchBar, TopVisitedCard, VisitListener, dynamicHomePagePlugin } from './plugin.esm.js';
1
+ export { CatalogStarredEntitiesCard, DynamicCustomizableHomePage, DynamicHomePage, FeaturedDocsCard, Headline, JokeCard, Markdown, MarkdownCard, Placeholder, QuickAccessCard, RecentlyVisitedCard, SearchBar, TopVisitedCard, VisitListener, WorldClock, dynamicHomePagePlugin } from './plugin.esm.js';
2
2
  //# sourceMappingURL=index.esm.js.map
@@ -35,6 +35,15 @@ const DynamicHomePage = dynamicHomePagePlugin.provide(
35
35
  mountPoint: rootRouteRef
36
36
  })
37
37
  );
38
+ const DynamicCustomizableHomePage = dynamicHomePagePlugin.provide(
39
+ createRoutableExtension({
40
+ name: "DynamicCustomizableHomePage",
41
+ component: () => import('./components/DynamicCustomizableHomePage.esm.js').then(
42
+ (m) => m.DynamicCustomizableHomePage
43
+ ),
44
+ mountPoint: rootRouteRef
45
+ })
46
+ );
38
47
  const SearchBar = dynamicHomePagePlugin.provide(
39
48
  createComponentExtension({
40
49
  name: "SearchBar",
@@ -131,6 +140,14 @@ const VisitListener = dynamicHomePagePlugin.provide(
131
140
  }
132
141
  })
133
142
  );
143
+ const WorldClock = dynamicHomePagePlugin.provide(
144
+ createComponentExtension({
145
+ name: "WorldClock",
146
+ component: {
147
+ lazy: () => import('./components/WorldClock.esm.js').then((m) => m.WorldClock)
148
+ }
149
+ })
150
+ );
134
151
 
135
- export { CatalogStarredEntitiesCard, DynamicHomePage, FeaturedDocsCard, Headline, JokeCard, Markdown, MarkdownCard, Placeholder, QuickAccessCard, RecentlyVisitedCard, SearchBar, TopVisitedCard, VisitListener, dynamicHomePagePlugin };
152
+ export { CatalogStarredEntitiesCard, DynamicCustomizableHomePage, DynamicHomePage, FeaturedDocsCard, Headline, JokeCard, Markdown, MarkdownCard, Placeholder, QuickAccessCard, RecentlyVisitedCard, SearchBar, TopVisitedCard, VisitListener, WorldClock, dynamicHomePagePlugin };
136
153
  //# sourceMappingURL=plugin.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React 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 { QuickAccessApiClient, quickAccessApiRef } from './api';\nimport { rootRouteRef } from './routes';\n\nimport type { DynamicHomePageProps } from './components/DynamicHomePage';\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 { 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';\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: React.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 * @public\n */\nexport const SearchBar: React.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: React.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: React.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: React.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: React.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: React.ComponentType<PlaceholderProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'MarkdownCard',\n component: {\n lazy: () => import('./components/Placeholder').then(m => m.Placeholder),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const CatalogStarredEntitiesCard: React.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: React.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: React.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: React.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: React.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"],"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 React 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 { QuickAccessApiClient, quickAccessApiRef } from './api';\nimport { rootRouteRef } from './routes';\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';\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: React.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: React.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: React.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: React.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: React.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: React.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: React.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: React.ComponentType<PlaceholderProps> =\n dynamicHomePagePlugin.provide(\n createComponentExtension({\n name: 'MarkdownCard',\n component: {\n lazy: () => import('./components/Placeholder').then(m => m.Placeholder),\n },\n }),\n );\n\n/**\n * @public\n */\nexport const CatalogStarredEntitiesCard: React.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: React.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: React.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: React.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: React.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"],"names":[],"mappings":";;;;;AAgEO,MAAM,wBAAwB,YAAa,CAAA;AAAA,EAChD,EAAI,EAAA,mBAAA;AAAA,EACJ,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA;AAAA,GACR;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,gBAAiB,CAAA;AAAA,MACf,GAAK,EAAA,iBAAA;AAAA,MACL,IAAM,EAAA;AAAA,QACJ,YAAc,EAAA,eAAA;AAAA,QACd,SAAW,EAAA,YAAA;AAAA,QACX,WAAa,EAAA;AAAA,OACf;AAAA,MACA,OAAS,EAAA,CAAC,EAAE,YAAA,EAAc,SAAW,EAAA,WAAA,EACnC,KAAA,IAAI,oBAAqB,CAAA,EAAE,YAAc,EAAA,SAAA,EAAW,aAAa;AAAA,KACpE,CAAA;AAAA,IACD,gBAAiB,CAAA;AAAA,MACf,GAAK,EAAA,YAAA;AAAA,MACL,IAAM,EAAA;AAAA,QACJ,UAAY,EAAA,aAAA;AAAA,QACZ,WAAa,EAAA;AAAA,OACf;AAAA,MACA,OAAA,EAAS,CAAC,EAAE,UAAY,EAAA,WAAA,EACtB,KAAA,gBAAA,CAAiB,MAAO,CAAA,EAAE,UAAY,EAAA,WAAA,EAAa;AAAA,KACtD;AAAA;AAEL,CAAC;AAMM,MAAM,kBACX,qBAAsB,CAAA,OAAA;AAAA,EACpB,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,iBAAA;AAAA,IACN,SAAA,EAAW,MACT,OAAO,qCAA8B,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,eAAe,CAAA;AAAA,IACpE,UAAY,EAAA;AAAA,GACb;AACH;AAMK,MAAM,8BACX,qBAAsB,CAAA,OAAA;AAAA,EACpB,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,6BAAA;AAAA,IACN,SAAW,EAAA,MACT,OAAO,iDAA0C,CAAE,CAAA,IAAA;AAAA,MACjD,OAAK,CAAE,CAAA;AAAA,KACT;AAAA,IACF,UAAY,EAAA;AAAA,GACb;AACH;AAKK,MAAM,YACX,qBAAsB,CAAA,OAAA;AAAA,EACpB,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,WAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAA,EAAM,MAAM,OAAO,+BAAwB,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,SAAS;AAAA;AACpE,GACD;AACH;AAKK,MAAM,kBACX,qBAAsB,CAAA,OAAA;AAAA,EACpB,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,iBAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAA,EAAM,MACJ,OAAO,qCAA8B,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,eAAe;AAAA;AACtE,GACD;AACH;AAKK,MAAM,WACX,qBAAsB,CAAA,OAAA;AAAA,EACpB,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,UAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAA,EAAM,MAAM,OAAO,8BAAuB,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,QAAQ;AAAA;AAClE,GACD;AACH;AAKK,MAAM,WACX,qBAAsB,CAAA,OAAA;AAAA,EACpB,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,UAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAA,EAAM,MAAM,OAAO,8BAAuB,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,QAAQ;AAAA;AAClE,GACD;AACH;AAKK,MAAM,eACX,qBAAsB,CAAA,OAAA;AAAA,EACpB,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,cAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAA,EAAM,MACJ,OAAO,kCAA2B,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,YAAY;AAAA;AAChE,GACD;AACH;AAKK,MAAM,cACX,qBAAsB,CAAA,OAAA;AAAA,EACpB,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,cAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAA,EAAM,MAAM,OAAO,iCAA0B,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,WAAW;AAAA;AACxE,GACD;AACH;AAKK,MAAM,6BACX,qBAAsB,CAAA,OAAA;AAAA,EACpB,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,4BAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAA,EAAM,MACJ,OAAO,wBAAwB,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,uBAAuB;AAAA;AACxE,GACD;AACH;AAKK,MAAM,sBACX,qBAAsB,CAAA,OAAA;AAAA,EACpB,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,qBAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAA,EAAM,MACJ,OAAO,wBAAwB,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,uBAAuB;AAAA;AACxE,GACD;AACH;AAKK,MAAM,iBACX,qBAAsB,CAAA,OAAA;AAAA,EACpB,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,gBAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAA,EAAM,MACJ,OAAO,wBAAwB,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,kBAAkB;AAAA;AACnE,GACD;AACH;AAKK,MAAM,mBACX,qBAAsB,CAAA,OAAA;AAAA,EACpB,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,kBAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAA,EAAM,MACJ,OAAO,sCAA+B,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,gBAAgB;AAAA;AACxE,GACD;AACH;AAKK,MAAM,WAER,qBAAsB,CAAA,OAAA;AAAA,EACzB,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,UAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAA,EAAM,MACJ,OAAO,wBAAwB,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,kBAAkB;AAAA;AACnE,GACD;AACH;AAKO,MAAM,gBAAgB,qBAAsB,CAAA,OAAA;AAAA,EACjD,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,eAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAA,EAAM,MACJ,OAAO,mCAA4B,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,aAAa;AAAA;AAClE,GACD;AACH;AAKO,MAAM,aAAa,qBAAsB,CAAA,OAAA;AAAA,EAC9C,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,YAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAA,EAAM,MAAM,OAAO,gCAAyB,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,UAAU;AAAA;AACtE,GACD;AACH;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"routes.esm.js","sources":["../src/routes.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'dynamic-home-page',\n});\n"],"names":[],"mappings":";;AAiBO,MAAM,eAAe,cAAe,CAAA;AAAA,EACzC,EAAI,EAAA;AACN,CAAC;;;;"}
1
+ {"version":3,"file":"routes.esm.js","sources":["../src/routes.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 { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'dynamic-home-page',\n});\n"],"names":[],"mappings":";;AAkBO,MAAM,eAAe,cAAe,CAAA;AAAA,EACzC,EAAI,EAAA;AACN,CAAC;;;;"}
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.0.3",
3
+ "version": "1.2.0",
4
4
  "main": "dist/index.esm.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -32,30 +32,30 @@
32
32
  "postpack": "backstage-cli package postpack"
33
33
  },
34
34
  "dependencies": {
35
- "@backstage/core-components": "0.15.1",
36
- "@backstage/core-plugin-api": "1.10.0",
37
- "@backstage/plugin-catalog-react": "1.14.0",
38
- "@backstage/plugin-home": "0.8.0",
39
- "@backstage/plugin-home-react": "0.1.18",
40
- "@backstage/plugin-search-react": "1.8.1",
41
- "@backstage/theme": "0.6.0",
42
- "@mui/material": "5.16.13",
43
- "@mui/styles": "5.16.13",
35
+ "@backstage/core-components": "^0.16.3",
36
+ "@backstage/core-plugin-api": "^1.10.3",
37
+ "@backstage/plugin-catalog-react": "^1.15.1",
38
+ "@backstage/plugin-home": "^0.8.4",
39
+ "@backstage/plugin-home-react": "^0.1.22",
40
+ "@backstage/plugin-search-react": "^1.8.5",
41
+ "@backstage/theme": "^0.6.3",
42
+ "@mui/material": "5.16.14",
43
+ "@mui/styles": "5.16.14",
44
44
  "@scalprum/react-core": "0.9.3",
45
45
  "react-grid-layout": "1.5.0",
46
46
  "react-use": "17.6.0",
47
- "tss-react": "4.9.14"
47
+ "tss-react": "4.9.15"
48
48
  },
49
49
  "peerDependencies": {
50
50
  "react": "16.13.1 || ^17.0.0 || ^18.2.0",
51
- "react-router-dom": "6.28.1"
51
+ "react-router-dom": "6.30.0"
52
52
  },
53
53
  "devDependencies": {
54
- "@backstage/cli": "0.28.2",
55
- "@backstage/core-app-api": "1.15.1",
56
- "@backstage/dev-utils": "1.1.2",
57
- "@backstage/plugin-catalog": "^1.24.0",
58
- "@backstage/test-utils": "1.7.0",
54
+ "@backstage/cli": "^0.29.5",
55
+ "@backstage/core-app-api": "^1.15.4",
56
+ "@backstage/dev-utils": "^1.1.6",
57
+ "@backstage/plugin-catalog": "^1.26.1",
58
+ "@backstage/test-utils": "^1.7.4",
59
59
  "@openshift/dynamic-plugin-sdk": "5.0.1",
60
60
  "@redhat-developer/red-hat-developer-hub-theme": "0.4.0",
61
61
  "@testing-library/jest-dom": "6.6.3",
@@ -69,5 +69,12 @@
69
69
  "app-config.dynamic.yaml",
70
70
  "dist"
71
71
  ],
72
+ "typesVersions": {
73
+ "*": {
74
+ "index": [
75
+ "dist/index.d.ts"
76
+ ]
77
+ }
78
+ },
72
79
  "module": "./dist/index.esm.js"
73
80
  }
@@ -1,10 +0,0 @@
1
- import { useScalprum } from '@scalprum/react-core';
2
-
3
- const useHomePageMountPoints = () => {
4
- const scalprum = useScalprum();
5
- const homePageMountPoints = scalprum?.api?.dynamicRootConfig?.mountPoints?.["home.page/cards"];
6
- return homePageMountPoints;
7
- };
8
-
9
- export { useHomePageMountPoints };
10
- //# sourceMappingURL=useHomePageMountPoints.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useHomePageMountPoints.esm.js","sources":["../../src/hooks/useHomePageMountPoints.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useScalprum } from '@scalprum/react-core';\n\nimport { HomePageCardMountPoint } from '../types';\n\ninterface ScalprumState {\n api?: {\n dynamicRootConfig?: {\n mountPoints?: {\n 'home.page/cards': HomePageCardMountPoint[];\n };\n };\n };\n}\n\nexport const useHomePageMountPoints = ():\n | HomePageCardMountPoint[]\n | undefined => {\n const scalprum = useScalprum<ScalprumState>();\n\n const homePageMountPoints =\n scalprum?.api?.dynamicRootConfig?.mountPoints?.['home.page/cards'];\n\n return homePageMountPoints;\n};\n"],"names":[],"mappings":";;AA6BO,MAAM,yBAAyB,MAErB;AACf,EAAA,MAAM,WAAW,WAA2B,EAAA;AAE5C,EAAA,MAAM,mBACJ,GAAA,QAAA,EAAU,GAAK,EAAA,iBAAA,EAAmB,cAAc,iBAAiB,CAAA;AAEnE,EAAO,OAAA,mBAAA;AACT;;;;"}