@red-hat-developer-hub/backstage-plugin-global-header 1.11.2 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/app-config.dynamic.yaml +11 -1
- package/config.d.ts +7 -0
- package/dist/components/CompanyLogo/CompanyLogo.esm.js +11 -5
- package/dist/components/CompanyLogo/CompanyLogo.esm.js.map +1 -1
- package/dist/components/HeaderDropdownComponent/HelpDropdown.esm.js +45 -0
- package/dist/components/HeaderDropdownComponent/HelpDropdown.esm.js.map +1 -0
- package/dist/components/HeaderDropdownComponent/ProfileDropdown.esm.js +35 -11
- package/dist/components/HeaderDropdownComponent/ProfileDropdown.esm.js.map +1 -1
- package/dist/components/QuickstartButton/QuickstartButton.esm.js +34 -0
- package/dist/components/QuickstartButton/QuickstartButton.esm.js.map +1 -0
- package/dist/components/QuickstartButton/const.esm.js +4 -0
- package/dist/components/QuickstartButton/const.esm.js.map +1 -0
- package/dist/components/QuickstartButton/useQuickstartButtonPermission.esm.js +27 -0
- package/dist/components/QuickstartButton/useQuickstartButtonPermission.esm.js.map +1 -0
- package/dist/components/SupportButton/SupportButton.esm.js +19 -23
- package/dist/components/SupportButton/SupportButton.esm.js.map +1 -1
- package/dist/defaultMountPoints/defaultMountPoints.esm.js +28 -2
- package/dist/defaultMountPoints/defaultMountPoints.esm.js.map +1 -1
- package/dist/hooks/useHelpDropdownMountPoints.esm.js +14 -0
- package/dist/hooks/useHelpDropdownMountPoints.esm.js.map +1 -0
- package/dist/index.d.ts +128 -110
- package/dist/index.esm.js +1 -1
- package/dist/plugin.esm.js +14 -3
- package/dist/plugin.esm.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @red-hat-developer-hub/backstage-plugin-global-header
|
|
2
2
|
|
|
3
|
+
## 1.13.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ba5e13c: Add dynamic profile link support to ProfileDropdown based on current user identity.
|
|
8
|
+
|
|
9
|
+
## 1.12.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 667e8c2: **BREAKING**: The `CompanyLogo` prop `logoWidth` has been renamed to `width`.
|
|
14
|
+
|
|
15
|
+
Allow configuring `width` and `height` for `CompanyLogo` via configuration. When `width` is not specified, `CompanyLogo` will now fall back to using the value from `app.branding.fullLogoWidth`.
|
|
16
|
+
|
|
17
|
+
- 5000863: **BREAKING**: `SupportButton` is now a `MenuItem` and `style` config prop can be used to update color, size and other required css properties.
|
|
18
|
+
|
|
19
|
+
Add `HelpDropdown` in global header plugin.
|
|
20
|
+
|
|
21
|
+
- 5638ede: Add QuickstartButton to global header plugin
|
|
22
|
+
|
|
3
23
|
## 1.11.2
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
package/app-config.dynamic.yaml
CHANGED
|
@@ -67,10 +67,20 @@ dynamicPlugins:
|
|
|
67
67
|
link: https://github.com/redhat-developer/rhdh-local
|
|
68
68
|
|
|
69
69
|
- mountPoint: global.header/component
|
|
70
|
-
importName:
|
|
70
|
+
importName: HelpDropdown
|
|
71
71
|
config:
|
|
72
72
|
priority: 80
|
|
73
73
|
|
|
74
|
+
- mountPoint: global.header/help
|
|
75
|
+
importName: QuickstartButton
|
|
76
|
+
config:
|
|
77
|
+
priority: 100
|
|
78
|
+
|
|
79
|
+
- mountPoint: global.header/help
|
|
80
|
+
importName: SupportButton
|
|
81
|
+
config:
|
|
82
|
+
priority: 10
|
|
83
|
+
|
|
74
84
|
- mountPoint: global.header/component
|
|
75
85
|
importName: NotificationButton
|
|
76
86
|
config:
|
package/config.d.ts
CHANGED
|
@@ -38,6 +38,13 @@ declare module '@backstage/config' {
|
|
|
38
38
|
*/
|
|
39
39
|
dark: string;
|
|
40
40
|
};
|
|
41
|
+
/**
|
|
42
|
+
* Fallback width for the full logo in the global header.
|
|
43
|
+
* Accepts any valid CSS length (e.g. `'200px'`, `'12rem'`).
|
|
44
|
+
* Used only when a `width` prop isn’t supplied through the extension configuration.
|
|
45
|
+
* @visibility frontend
|
|
46
|
+
*/
|
|
47
|
+
fullLogoWidth?: string | number;
|
|
41
48
|
};
|
|
42
49
|
};
|
|
43
50
|
}
|
|
@@ -8,7 +8,8 @@ import { useAppBarBackgroundScheme } from '../../hooks/useAppBarBackgroundScheme
|
|
|
8
8
|
const LogoRender = ({
|
|
9
9
|
base64Logo,
|
|
10
10
|
defaultLogo,
|
|
11
|
-
width = 150
|
|
11
|
+
width = 150,
|
|
12
|
+
height = 40
|
|
12
13
|
}) => {
|
|
13
14
|
return base64Logo ? /* @__PURE__ */ jsx(
|
|
14
15
|
"img",
|
|
@@ -19,8 +20,7 @@ const LogoRender = ({
|
|
|
19
20
|
style: {
|
|
20
21
|
objectFit: "contain",
|
|
21
22
|
objectPosition: "left",
|
|
22
|
-
maxHeight:
|
|
23
|
-
// "kind of" aligns with PF's MastheadLogo height
|
|
23
|
+
maxHeight: height
|
|
24
24
|
},
|
|
25
25
|
width
|
|
26
26
|
}
|
|
@@ -36,10 +36,15 @@ const useFullLogo = (logo) => {
|
|
|
36
36
|
};
|
|
37
37
|
const CompanyLogo = ({
|
|
38
38
|
logo,
|
|
39
|
-
|
|
39
|
+
width,
|
|
40
|
+
height,
|
|
40
41
|
to = "/"
|
|
41
42
|
}) => {
|
|
42
43
|
const logoURL = useFullLogo(logo);
|
|
44
|
+
const configApi = useApi(configApiRef);
|
|
45
|
+
const fullLogoWidth = configApi.getOptional(
|
|
46
|
+
"app.branding.fullLogoWidth"
|
|
47
|
+
);
|
|
43
48
|
return /* @__PURE__ */ jsx(
|
|
44
49
|
Box,
|
|
45
50
|
{
|
|
@@ -68,7 +73,8 @@ const CompanyLogo = ({
|
|
|
68
73
|
{
|
|
69
74
|
base64Logo: logoURL,
|
|
70
75
|
defaultLogo: /* @__PURE__ */ jsx(DefaultLogo, {}),
|
|
71
|
-
width:
|
|
76
|
+
width: width ?? fullLogoWidth,
|
|
77
|
+
height
|
|
72
78
|
}
|
|
73
79
|
)
|
|
74
80
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompanyLogo.esm.js","sources":["../../../src/components/CompanyLogo/CompanyLogo.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 */\nimport type { CSSProperties } from 'react';\nimport { Link } from '@backstage/core-components';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport DefaultLogo from './DefaultLogo';\nimport Box from '@mui/material/Box';\nimport { useAppBarBackgroundScheme } from '../../hooks/useAppBarBackgroundScheme';\n\nconst LogoRender = ({\n base64Logo,\n defaultLogo,\n width = 150,\n}: {\n base64Logo: string | undefined;\n defaultLogo: JSX.Element;\n width?: number;\n}) => {\n return base64Logo ? (\n <img\n data-testid=\"home-logo\"\n src={base64Logo}\n alt=\"Home logo\"\n style={{\n objectFit: 'contain',\n objectPosition: 'left',\n maxHeight:
|
|
1
|
+
{"version":3,"file":"CompanyLogo.esm.js","sources":["../../../src/components/CompanyLogo/CompanyLogo.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 */\nimport type { CSSProperties } from 'react';\nimport { Link } from '@backstage/core-components';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport DefaultLogo from './DefaultLogo';\nimport Box from '@mui/material/Box';\nimport { useAppBarBackgroundScheme } from '../../hooks/useAppBarBackgroundScheme';\n\nconst LogoRender = ({\n base64Logo,\n defaultLogo,\n width = 150,\n height = 40,\n}: {\n base64Logo: string | undefined;\n defaultLogo: JSX.Element;\n width?: number | string;\n height?: number | string;\n}) => {\n return base64Logo ? (\n <img\n data-testid=\"home-logo\"\n src={base64Logo}\n alt=\"Home logo\"\n style={{\n objectFit: 'contain',\n objectPosition: 'left',\n maxHeight: height,\n }}\n width={width}\n />\n ) : (\n defaultLogo\n );\n};\n\n/**\n * An interface representing the URLs for light and dark variants of a logo.\n * @public\n */\nexport type LogoURLs =\n | {\n /** The logo that will be used in global headers with a light-coloured background */\n light: string;\n /** The logo that will be used in global headers with a dark-coloured background */\n dark: string;\n }\n | string\n | undefined;\n\n/**\n * @public\n */\nexport interface CompanyLogoProps {\n /** An object containing the logo URLs */\n logo?: LogoURLs;\n /** The route to link the logo to */\n to?: string;\n /**\n * The width of the logo in pixels (defaults to 150px). This prop fixes an\n * issue where encoded SVGs without an explicit width would not render.\n * You likely do not need to set this prop, but we recommend setting it\n * to a value under 200px.\n */\n width?: string | number;\n /**\n * The maximum height of the logo in pixels (defaults to 40px).\n * Note that changing this value may result in changes in the height of the global header.\n **/\n height?: string | number;\n /** This prop is not used by this component. */\n layout?: CSSProperties;\n}\n\n/**\n * Gets a themed image based on the current theme.\n */\nconst useFullLogo = (logo: LogoURLs): string | undefined => {\n const appBarBackgroundScheme = useAppBarBackgroundScheme();\n\n const configApi = useApi(configApiRef);\n\n /** The fullLogo config specified by app.branding.fullLogo */\n const fullLogo = configApi.getOptional<LogoURLs>('app.branding.fullLogo');\n\n /** The URI of the logo specified by app.branding.fullLogo */\n const fullLogoURI =\n typeof fullLogo === 'string'\n ? fullLogo\n : fullLogo?.[appBarBackgroundScheme];\n\n /** The URI of the logo specified by CompanyLogo props */\n const propsLogoURI =\n typeof logo === 'string' ? logo : logo?.[appBarBackgroundScheme];\n\n return propsLogoURI ?? fullLogoURI ?? undefined;\n};\n\nexport const CompanyLogo = ({\n logo,\n width,\n height,\n to = '/',\n}: CompanyLogoProps) => {\n const logoURL = useFullLogo(logo);\n const configApi = useApi(configApiRef);\n const fullLogoWidth = configApi.getOptional<number | string>(\n 'app.branding.fullLogoWidth',\n );\n return (\n <Box\n data-testid=\"global-header-company-logo\"\n sx={{\n minWidth: '200px',\n marginRight: '13px', // align with BackstageContent\n display: 'flex',\n justifyContent: 'flex-start',\n alignItems: 'center',\n }}\n >\n <Link\n to={to}\n underline=\"none\"\n aria-label=\"Home\"\n style={{\n display: 'flex',\n justifyContent: 'flex-start',\n alignItems: 'center',\n }}\n >\n <LogoRender\n base64Logo={logoURL}\n defaultLogo={<DefaultLogo />}\n width={width ?? fullLogoWidth}\n height={height}\n />\n </Link>\n </Box>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAsBA,MAAM,aAAa,CAAC;AAAA,EAClB,UAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAQ,GAAA,GAAA;AAAA,EACR,MAAS,GAAA;AACX,CAKM,KAAA;AACJ,EAAA,OAAO,UACL,mBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,aAAY,EAAA,WAAA;AAAA,MACZ,GAAK,EAAA,UAAA;AAAA,MACL,GAAI,EAAA,WAAA;AAAA,MACJ,KAAO,EAAA;AAAA,QACL,SAAW,EAAA,SAAA;AAAA,QACX,cAAgB,EAAA,MAAA;AAAA,QAChB,SAAW,EAAA;AAAA,OACb;AAAA,MACA;AAAA;AAAA,GAGF,GAAA,WAAA;AAEJ,CAAA;AA2CA,MAAM,WAAA,GAAc,CAAC,IAAuC,KAAA;AAC1D,EAAA,MAAM,yBAAyB,yBAA0B,EAAA;AAEzD,EAAM,MAAA,SAAA,GAAY,OAAO,YAAY,CAAA;AAGrC,EAAM,MAAA,QAAA,GAAW,SAAU,CAAA,WAAA,CAAsB,uBAAuB,CAAA;AAGxE,EAAA,MAAM,cACJ,OAAO,QAAA,KAAa,QAChB,GAAA,QAAA,GACA,WAAW,sBAAsB,CAAA;AAGvC,EAAA,MAAM,eACJ,OAAO,IAAA,KAAS,QAAW,GAAA,IAAA,GAAO,OAAO,sBAAsB,CAAA;AAEjE,EAAA,OAAO,gBAAgB,WAAe,IAAA,KAAA,CAAA;AACxC,CAAA;AAEO,MAAM,cAAc,CAAC;AAAA,EAC1B,IAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,EAAK,GAAA;AACP,CAAwB,KAAA;AACtB,EAAM,MAAA,OAAA,GAAU,YAAY,IAAI,CAAA;AAChC,EAAM,MAAA,SAAA,GAAY,OAAO,YAAY,CAAA;AACrC,EAAA,MAAM,gBAAgB,SAAU,CAAA,WAAA;AAAA,IAC9B;AAAA,GACF;AACA,EACE,uBAAA,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,aAAY,EAAA,4BAAA;AAAA,MACZ,EAAI,EAAA;AAAA,QACF,QAAU,EAAA,OAAA;AAAA,QACV,WAAa,EAAA,MAAA;AAAA;AAAA,QACb,OAAS,EAAA,MAAA;AAAA,QACT,cAAgB,EAAA,YAAA;AAAA,QAChB,UAAY,EAAA;AAAA,OACd;AAAA,MAEA,QAAA,kBAAA,GAAA;AAAA,QAAC,IAAA;AAAA,QAAA;AAAA,UACC,EAAA;AAAA,UACA,SAAU,EAAA,MAAA;AAAA,UACV,YAAW,EAAA,MAAA;AAAA,UACX,KAAO,EAAA;AAAA,YACL,OAAS,EAAA,MAAA;AAAA,YACT,cAAgB,EAAA,YAAA;AAAA,YAChB,UAAY,EAAA;AAAA,WACd;AAAA,UAEA,QAAA,kBAAA,GAAA;AAAA,YAAC,UAAA;AAAA,YAAA;AAAA,cACC,UAAY,EAAA,OAAA;AAAA,cACZ,WAAA,sBAAc,WAAY,EAAA,EAAA,CAAA;AAAA,cAC1B,OAAO,KAAS,IAAA,aAAA;AAAA,cAChB;AAAA;AAAA;AACF;AAAA;AACF;AAAA,GACF;AAEJ;;;;"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { HeaderDropdownComponent } from './HeaderDropdownComponent.esm.js';
|
|
4
|
+
import { useDropdownManager } from '../../hooks/useDropdownManager.esm.js';
|
|
5
|
+
import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
|
|
6
|
+
import { useHelpDropdownMountPoints } from '../../hooks/useHelpDropdownMountPoints.esm.js';
|
|
7
|
+
import { MenuSection } from './MenuSection.esm.js';
|
|
8
|
+
|
|
9
|
+
const HelpDropdown = ({ layout }) => {
|
|
10
|
+
const { anchorEl, handleOpen, handleClose } = useDropdownManager();
|
|
11
|
+
const helpDropdownMountPoints = useHelpDropdownMountPoints();
|
|
12
|
+
const menuItems = useMemo(() => {
|
|
13
|
+
return (helpDropdownMountPoints ?? []).map((mp) => ({
|
|
14
|
+
Component: mp.Component,
|
|
15
|
+
icon: mp.config?.props?.icon,
|
|
16
|
+
label: mp.config?.props?.title,
|
|
17
|
+
link: mp.config?.props?.link,
|
|
18
|
+
tooltip: mp.config?.props?.tooltip,
|
|
19
|
+
style: mp.config?.style,
|
|
20
|
+
priority: mp.config?.priority ?? 0
|
|
21
|
+
})).sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
22
|
+
}, [helpDropdownMountPoints]);
|
|
23
|
+
if (menuItems.length === 0) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return /* @__PURE__ */ jsx(
|
|
27
|
+
HeaderDropdownComponent,
|
|
28
|
+
{
|
|
29
|
+
isIconButton: true,
|
|
30
|
+
tooltip: "Help",
|
|
31
|
+
buttonContent: /* @__PURE__ */ jsx(HelpOutlineIcon, {}),
|
|
32
|
+
buttonProps: {
|
|
33
|
+
color: "inherit",
|
|
34
|
+
sx: layout
|
|
35
|
+
},
|
|
36
|
+
onOpen: handleOpen,
|
|
37
|
+
onClose: handleClose,
|
|
38
|
+
anchorEl,
|
|
39
|
+
children: /* @__PURE__ */ jsx(MenuSection, { hideDivider: true, items: menuItems, handleClose })
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export { HelpDropdown };
|
|
45
|
+
//# sourceMappingURL=HelpDropdown.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HelpDropdown.esm.js","sources":["../../../src/components/HeaderDropdownComponent/HelpDropdown.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 { useMemo } from 'react';\nimport type { CSSProperties } from 'react';\nimport { HeaderDropdownComponent } from './HeaderDropdownComponent';\nimport { useDropdownManager } from '../../hooks';\nimport HelpOutlineIcon from '@mui/icons-material/HelpOutline';\nimport { useHelpDropdownMountPoints } from '../../hooks/useHelpDropdownMountPoints';\nimport { MenuSection } from './MenuSection';\n\n/**\n * @public\n * Props for Help Dropdown\n */\nexport interface HelpDropdownProps {\n layout?: CSSProperties;\n}\n\nexport const HelpDropdown = ({ layout }: HelpDropdownProps) => {\n const { anchorEl, handleOpen, handleClose } = useDropdownManager();\n\n const helpDropdownMountPoints = useHelpDropdownMountPoints();\n\n const menuItems = useMemo(() => {\n return (helpDropdownMountPoints ?? [])\n .map(mp => ({\n Component: mp.Component,\n icon: mp.config?.props?.icon,\n label: mp.config?.props?.title,\n link: mp.config?.props?.link,\n tooltip: mp.config?.props?.tooltip,\n style: mp.config?.style,\n priority: mp.config?.priority ?? 0,\n }))\n .sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));\n }, [helpDropdownMountPoints]);\n\n if (menuItems.length === 0) {\n return null;\n }\n\n return (\n <HeaderDropdownComponent\n isIconButton\n tooltip=\"Help\"\n buttonContent={<HelpOutlineIcon />}\n buttonProps={{\n color: 'inherit',\n sx: layout,\n }}\n onOpen={handleOpen}\n onClose={handleClose}\n anchorEl={anchorEl}\n >\n <MenuSection hideDivider items={menuItems} handleClose={handleClose} />\n </HeaderDropdownComponent>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAgCO,MAAM,YAAe,GAAA,CAAC,EAAE,MAAA,EAAgC,KAAA;AAC7D,EAAA,MAAM,EAAE,QAAA,EAAU,UAAY,EAAA,WAAA,KAAgB,kBAAmB,EAAA;AAEjE,EAAA,MAAM,0BAA0B,0BAA2B,EAAA;AAE3D,EAAM,MAAA,SAAA,GAAY,QAAQ,MAAM;AAC9B,IAAA,OAAA,CAAQ,uBAA2B,IAAA,EAChC,EAAA,GAAA,CAAI,CAAO,EAAA,MAAA;AAAA,MACV,WAAW,EAAG,CAAA,SAAA;AAAA,MACd,IAAA,EAAM,EAAG,CAAA,MAAA,EAAQ,KAAO,EAAA,IAAA;AAAA,MACxB,KAAA,EAAO,EAAG,CAAA,MAAA,EAAQ,KAAO,EAAA,KAAA;AAAA,MACzB,IAAA,EAAM,EAAG,CAAA,MAAA,EAAQ,KAAO,EAAA,IAAA;AAAA,MACxB,OAAA,EAAS,EAAG,CAAA,MAAA,EAAQ,KAAO,EAAA,OAAA;AAAA,MAC3B,KAAA,EAAO,GAAG,MAAQ,EAAA,KAAA;AAAA,MAClB,QAAA,EAAU,EAAG,CAAA,MAAA,EAAQ,QAAY,IAAA;AAAA,KACnC,CAAE,CACD,CAAA,IAAA,CAAK,CAAC,CAAA,EAAG,CAAO,KAAA,CAAA,CAAA,CAAE,QAAY,IAAA,CAAA,KAAM,CAAE,CAAA,QAAA,IAAY,CAAE,CAAA,CAAA;AAAA,GACzD,EAAG,CAAC,uBAAuB,CAAC,CAAA;AAE5B,EAAI,IAAA,SAAA,CAAU,WAAW,CAAG,EAAA;AAC1B,IAAO,OAAA,IAAA;AAAA;AAGT,EACE,uBAAA,GAAA;AAAA,IAAC,uBAAA;AAAA,IAAA;AAAA,MACC,YAAY,EAAA,IAAA;AAAA,MACZ,OAAQ,EAAA,MAAA;AAAA,MACR,aAAA,sBAAgB,eAAgB,EAAA,EAAA,CAAA;AAAA,MAChC,WAAa,EAAA;AAAA,QACX,KAAO,EAAA,SAAA;AAAA,QACP,EAAI,EAAA;AAAA,OACN;AAAA,MACA,MAAQ,EAAA,UAAA;AAAA,MACR,OAAS,EAAA,WAAA;AAAA,MACT,QAAA;AAAA,MAEA,8BAAC,WAAY,EAAA,EAAA,WAAA,EAAW,IAAC,EAAA,KAAA,EAAO,WAAW,WAA0B,EAAA;AAAA;AAAA,GACvE;AAEJ;;;;"}
|
|
@@ -3,6 +3,7 @@ import { useState, useRef, useEffect, useMemo } from 'react';
|
|
|
3
3
|
import { useUserProfile } from '@backstage/plugin-user-settings';
|
|
4
4
|
import { useApi } from '@backstage/core-plugin-api';
|
|
5
5
|
import { catalogApiRef } from '@backstage/plugin-catalog-react';
|
|
6
|
+
import { parseEntityRef } from '@backstage/catalog-model';
|
|
6
7
|
import AccountCircleOutlinedIcon from '@mui/icons-material/AccountCircleOutlined';
|
|
7
8
|
import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined';
|
|
8
9
|
import Avatar from '@mui/material/Avatar';
|
|
@@ -17,6 +18,7 @@ import { useDropdownManager } from '../../hooks/useDropdownManager.esm.js';
|
|
|
17
18
|
const ProfileDropdown = ({ layout }) => {
|
|
18
19
|
const { anchorEl, handleOpen, handleClose } = useDropdownManager();
|
|
19
20
|
const [user, setUser] = useState();
|
|
21
|
+
const [profileLink, setProfileLink] = useState();
|
|
20
22
|
const {
|
|
21
23
|
displayName,
|
|
22
24
|
backstageIdentity,
|
|
@@ -45,30 +47,52 @@ const ProfileDropdown = ({ layout }) => {
|
|
|
45
47
|
useEffect(() => {
|
|
46
48
|
const fetchUserEntity = async () => {
|
|
47
49
|
let userProfile;
|
|
50
|
+
let profileUrl = null;
|
|
48
51
|
try {
|
|
49
52
|
if (backstageIdentity?.userEntityRef) {
|
|
53
|
+
const { namespace = "default", name } = parseEntityRef(
|
|
54
|
+
backstageIdentity.userEntityRef
|
|
55
|
+
);
|
|
56
|
+
profileUrl = `/catalog/${namespace}/user/${name}`;
|
|
50
57
|
userProfile = await catalogApi.getEntityByRef(
|
|
51
58
|
backstageIdentity.userEntityRef
|
|
52
59
|
);
|
|
60
|
+
setUser(
|
|
61
|
+
userProfile?.spec?.profile?.displayName ?? userProfile?.metadata?.title
|
|
62
|
+
);
|
|
63
|
+
setProfileLink(profileUrl);
|
|
64
|
+
} else {
|
|
65
|
+
setUser(null);
|
|
66
|
+
setProfileLink(null);
|
|
53
67
|
}
|
|
54
|
-
setUser(
|
|
55
|
-
userProfile?.spec?.profile?.displayName ?? userProfile?.metadata?.title
|
|
56
|
-
);
|
|
57
68
|
} catch (_err) {
|
|
58
69
|
setUser(null);
|
|
70
|
+
setProfileLink(null);
|
|
59
71
|
}
|
|
60
72
|
};
|
|
61
73
|
fetchUserEntity();
|
|
62
74
|
}, [backstageIdentity, catalogApi]);
|
|
63
75
|
const menuItems = useMemo(() => {
|
|
64
|
-
return (profileDropdownMountPoints ?? []).map((mp) =>
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
76
|
+
return (profileDropdownMountPoints ?? []).map((mp) => {
|
|
77
|
+
const {
|
|
78
|
+
title = "",
|
|
79
|
+
icon = "",
|
|
80
|
+
link: staticLink = ""
|
|
81
|
+
} = mp.config?.props ?? {};
|
|
82
|
+
const isMyProfile = title.toLowerCase() === "my profile";
|
|
83
|
+
const link = isMyProfile ? profileLink ?? "" : staticLink;
|
|
84
|
+
if (!link && title) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
Component: mp.Component,
|
|
89
|
+
label: title,
|
|
90
|
+
link,
|
|
91
|
+
priority: mp.config?.priority ?? 0,
|
|
92
|
+
...icon && { icon }
|
|
93
|
+
};
|
|
94
|
+
}).filter((item) => item !== null).sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
95
|
+
}, [profileDropdownMountPoints, profileLink]);
|
|
72
96
|
if (menuItems.length === 0) {
|
|
73
97
|
return null;
|
|
74
98
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProfileDropdown.esm.js","sources":["../../../src/components/HeaderDropdownComponent/ProfileDropdown.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 { useEffect, useMemo, useRef, useState } from 'react';\nimport type { CSSProperties } from 'react';\nimport { useUserProfile } from '@backstage/plugin-user-settings';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport { UserEntity } from '@backstage/catalog-model';\nimport AccountCircleOutlinedIcon from '@mui/icons-material/AccountCircleOutlined';\nimport KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined';\nimport Avatar from '@mui/material/Avatar';\nimport Typography from '@mui/material/Typography';\nimport { lighten } from '@mui/material/styles';\nimport Box from '@mui/material/Box';\n\nimport { MenuSection } from './MenuSection';\nimport { HeaderDropdownComponent } from './HeaderDropdownComponent';\nimport { useProfileDropdownMountPoints } from '../../hooks/useProfileDropdownMountPoints';\nimport { useDropdownManager } from '../../hooks';\n\n/**\n * @public\n * Props for Profile Dropdown\n */\nexport interface ProfileDropdownProps {\n layout?: CSSProperties;\n}\n\nexport const ProfileDropdown = ({ layout }: ProfileDropdownProps) => {\n const { anchorEl, handleOpen, handleClose } = useDropdownManager();\n const [user, setUser] = useState<string | null>();\n const {\n displayName,\n backstageIdentity,\n profile,\n loading: profileLoading,\n } = useUserProfile();\n const catalogApi = useApi(catalogApiRef);\n\n const profileDropdownMountPoints = useProfileDropdownMountPoints();\n\n const headerRef = useRef<HTMLElement | null>(null);\n const [bgColor, setBgColor] = useState('#3C3F42');\n\n useEffect(() => {\n if (headerRef.current) {\n const computedStyle = window.getComputedStyle(headerRef.current);\n const baseColor = computedStyle.backgroundColor;\n setBgColor(lighten(baseColor, 0.2));\n }\n }, []);\n\n useEffect(() => {\n const container = document.getElementById('global-header');\n if (container) {\n const computedStyle = window.getComputedStyle(container);\n const baseColor = computedStyle.backgroundColor;\n setBgColor(lighten(baseColor, 0.2));\n }\n }, []);\n\n useEffect(() => {\n const fetchUserEntity = async () => {\n let userProfile;\n try {\n if (backstageIdentity?.userEntityRef) {\n userProfile = (await catalogApi.getEntityByRef(\n backstageIdentity.userEntityRef,\n )) as unknown as UserEntity;\n }\n setUser(\n userProfile?.spec?.profile?.displayName ??\n userProfile?.metadata?.title,\n );\n } catch (_err) {\n setUser(null);\n }\n };\n\n fetchUserEntity();\n }, [backstageIdentity, catalogApi]);\n\n const menuItems = useMemo(() => {\n return (profileDropdownMountPoints ?? [])\n .map(mp => ({\n Component: mp.Component,\n icon: mp.config?.props?.icon ?? '',\n label: mp.config?.props?.title ?? '',\n link: mp.config?.props?.link ?? '',\n priority: mp.config?.priority ?? 0,\n }))\n .sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));\n }, [profileDropdownMountPoints]);\n\n if (menuItems.length === 0) {\n return null;\n }\n\n const profileDisplayName = () => {\n const name = user ?? displayName;\n const regex = /^[^:/]+:[^/]+\\/[^/]+$/;\n if (regex.test(name)) {\n return name\n .charAt(name.indexOf('/') + 1)\n .toLocaleUpperCase('en-US')\n .concat(name.substring(name.indexOf('/') + 2));\n }\n return name;\n };\n\n return (\n <HeaderDropdownComponent\n buttonContent={\n <Box sx={{ display: 'flex', alignItems: 'center', ...layout }}>\n {!profileLoading && (\n <>\n {profile.picture ? (\n <Avatar\n src={profile.picture}\n sx={{ mr: 2, height: '32px', width: '32px' }}\n alt=\"Profile picture\"\n />\n ) : (\n <AccountCircleOutlinedIcon fontSize=\"small\" sx={{ mr: 1 }} />\n )}\n <Typography\n variant=\"body2\"\n sx={{\n display: { xs: 'none', md: 'block' },\n fontWeight: 500,\n mr: '1rem',\n }}\n >\n {profileDisplayName()}\n </Typography>\n </>\n )}\n <KeyboardArrowDownOutlinedIcon\n sx={{\n bgcolor: bgColor,\n borderRadius: '25%',\n }}\n />\n </Box>\n }\n buttonProps={{\n color: 'inherit',\n sx: {\n display: 'flex',\n alignItems: 'center',\n },\n }}\n onOpen={handleOpen}\n onClose={handleClose}\n anchorEl={anchorEl}\n >\n <MenuSection hideDivider items={menuItems} handleClose={handleClose} />\n </HeaderDropdownComponent>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ProfileDropdown.esm.js","sources":["../../../src/components/HeaderDropdownComponent/ProfileDropdown.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 { useEffect, useMemo, useRef, useState } from 'react';\nimport type { CSSProperties } from 'react';\nimport { useUserProfile } from '@backstage/plugin-user-settings';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport { parseEntityRef, UserEntity } from '@backstage/catalog-model';\nimport AccountCircleOutlinedIcon from '@mui/icons-material/AccountCircleOutlined';\nimport KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined';\nimport Avatar from '@mui/material/Avatar';\nimport Typography from '@mui/material/Typography';\nimport { lighten } from '@mui/material/styles';\nimport Box from '@mui/material/Box';\n\nimport { MenuItemConfig, MenuSection } from './MenuSection';\nimport { HeaderDropdownComponent } from './HeaderDropdownComponent';\nimport { useProfileDropdownMountPoints } from '../../hooks/useProfileDropdownMountPoints';\nimport { useDropdownManager } from '../../hooks';\n\n/**\n * @public\n * Props for Profile Dropdown\n */\nexport interface ProfileDropdownProps {\n layout?: CSSProperties;\n}\n\nexport const ProfileDropdown = ({ layout }: ProfileDropdownProps) => {\n const { anchorEl, handleOpen, handleClose } = useDropdownManager();\n const [user, setUser] = useState<string | null>();\n const [profileLink, setProfileLink] = useState<string | null>();\n const {\n displayName,\n backstageIdentity,\n profile,\n loading: profileLoading,\n } = useUserProfile();\n const catalogApi = useApi(catalogApiRef);\n\n const profileDropdownMountPoints = useProfileDropdownMountPoints();\n\n const headerRef = useRef<HTMLElement | null>(null);\n const [bgColor, setBgColor] = useState('#3C3F42');\n\n useEffect(() => {\n if (headerRef.current) {\n const computedStyle = window.getComputedStyle(headerRef.current);\n const baseColor = computedStyle.backgroundColor;\n setBgColor(lighten(baseColor, 0.2));\n }\n }, []);\n\n useEffect(() => {\n const container = document.getElementById('global-header');\n if (container) {\n const computedStyle = window.getComputedStyle(container);\n const baseColor = computedStyle.backgroundColor;\n setBgColor(lighten(baseColor, 0.2));\n }\n }, []);\n\n useEffect(() => {\n const fetchUserEntity = async () => {\n let userProfile;\n let profileUrl: string | null = null;\n\n try {\n if (backstageIdentity?.userEntityRef) {\n const { namespace = 'default', name } = parseEntityRef(\n backstageIdentity.userEntityRef,\n );\n profileUrl = `/catalog/${namespace}/user/${name}`;\n\n userProfile = (await catalogApi.getEntityByRef(\n backstageIdentity.userEntityRef,\n )) as unknown as UserEntity;\n setUser(\n userProfile?.spec?.profile?.displayName ??\n userProfile?.metadata?.title,\n );\n setProfileLink(profileUrl);\n } else {\n setUser(null);\n setProfileLink(null);\n }\n } catch (_err) {\n setUser(null);\n setProfileLink(null);\n }\n };\n\n fetchUserEntity();\n }, [backstageIdentity, catalogApi]);\n\n const menuItems = useMemo(() => {\n return (profileDropdownMountPoints ?? [])\n .map(mp => {\n const {\n title = '',\n icon = '',\n link: staticLink = '',\n } = mp.config?.props ?? {};\n const isMyProfile = title.toLowerCase() === 'my profile';\n const link = isMyProfile ? profileLink ?? '' : staticLink;\n\n if (!link && title) {\n return null;\n }\n\n return {\n Component: mp.Component,\n label: title,\n link,\n priority: mp.config?.priority ?? 0,\n ...(icon && { icon }),\n };\n })\n .filter((item: MenuItemConfig) => item !== null)\n .sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));\n }, [profileDropdownMountPoints, profileLink]);\n\n if (menuItems.length === 0) {\n return null;\n }\n\n const profileDisplayName = () => {\n const name = user ?? displayName;\n const regex = /^[^:/]+:[^/]+\\/[^/]+$/;\n if (regex.test(name)) {\n return name\n .charAt(name.indexOf('/') + 1)\n .toLocaleUpperCase('en-US')\n .concat(name.substring(name.indexOf('/') + 2));\n }\n return name;\n };\n\n return (\n <HeaderDropdownComponent\n buttonContent={\n <Box sx={{ display: 'flex', alignItems: 'center', ...layout }}>\n {!profileLoading && (\n <>\n {profile.picture ? (\n <Avatar\n src={profile.picture}\n sx={{ mr: 2, height: '32px', width: '32px' }}\n alt=\"Profile picture\"\n />\n ) : (\n <AccountCircleOutlinedIcon fontSize=\"small\" sx={{ mr: 1 }} />\n )}\n <Typography\n variant=\"body2\"\n sx={{\n display: { xs: 'none', md: 'block' },\n fontWeight: 500,\n mr: '1rem',\n }}\n >\n {profileDisplayName()}\n </Typography>\n </>\n )}\n <KeyboardArrowDownOutlinedIcon\n sx={{\n bgcolor: bgColor,\n borderRadius: '25%',\n }}\n />\n </Box>\n }\n buttonProps={{\n color: 'inherit',\n sx: {\n display: 'flex',\n alignItems: 'center',\n },\n }}\n onOpen={handleOpen}\n onClose={handleClose}\n anchorEl={anchorEl}\n >\n <MenuSection hideDivider items={menuItems} handleClose={handleClose} />\n </HeaderDropdownComponent>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useCallback } from 'react';
|
|
3
|
+
import MenuItem from '@mui/material/MenuItem';
|
|
4
|
+
import { MenuItemLink } from '../MenuItemLink/MenuItemLink.esm.js';
|
|
5
|
+
import { QUICKSTART_DRAWER_OPEN_KEY } from './const.esm.js';
|
|
6
|
+
import { useQuickstartButtonPermission } from './useQuickstartButtonPermission.esm.js';
|
|
7
|
+
|
|
8
|
+
const QuickstartButton = ({
|
|
9
|
+
icon = "quickstart",
|
|
10
|
+
title = "Quick start",
|
|
11
|
+
tooltip,
|
|
12
|
+
style
|
|
13
|
+
}) => {
|
|
14
|
+
const isAllowed = useQuickstartButtonPermission();
|
|
15
|
+
const toggleDrawer = useCallback(() => {
|
|
16
|
+
const isDrawerOpen = localStorage.getItem(QUICKSTART_DRAWER_OPEN_KEY) === "true";
|
|
17
|
+
localStorage.setItem(
|
|
18
|
+
QUICKSTART_DRAWER_OPEN_KEY,
|
|
19
|
+
(!isDrawerOpen).toString()
|
|
20
|
+
);
|
|
21
|
+
}, []);
|
|
22
|
+
return isAllowed ? /* @__PURE__ */ jsx(
|
|
23
|
+
MenuItem,
|
|
24
|
+
{
|
|
25
|
+
sx: { width: "100%", color: "inherit", ...style },
|
|
26
|
+
"data-testid": "quickstart-button",
|
|
27
|
+
onClick: toggleDrawer,
|
|
28
|
+
children: /* @__PURE__ */ jsx(MenuItemLink, { to: "", title, icon, tooltip })
|
|
29
|
+
}
|
|
30
|
+
) : null;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export { QuickstartButton };
|
|
34
|
+
//# sourceMappingURL=QuickstartButton.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QuickstartButton.esm.js","sources":["../../../src/components/QuickstartButton/QuickstartButton.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 { CSSProperties, useCallback } from 'react';\nimport MenuItem from '@mui/material/MenuItem';\nimport { MenuItemLink } from '../MenuItemLink/MenuItemLink';\nimport { QUICKSTART_DRAWER_OPEN_KEY } from './const';\nimport { useQuickstartButtonPermission } from './useQuickstartButtonPermission';\n\n/**\n * @public\n */\nexport interface QuickstartButtonProps {\n icon?: string;\n title?: string;\n tooltip?: string;\n style?: CSSProperties;\n}\n\n/**\n * @public\n */\nexport const QuickstartButton = ({\n icon = 'quickstart',\n title = 'Quick start',\n tooltip,\n style,\n}: QuickstartButtonProps) => {\n const isAllowed = useQuickstartButtonPermission();\n const toggleDrawer = useCallback(() => {\n const isDrawerOpen =\n localStorage.getItem(QUICKSTART_DRAWER_OPEN_KEY) === 'true';\n localStorage.setItem(\n QUICKSTART_DRAWER_OPEN_KEY,\n (!isDrawerOpen).toString(),\n );\n }, []);\n\n return isAllowed ? (\n <MenuItem\n sx={{ width: '100%', color: 'inherit', ...style }}\n data-testid=\"quickstart-button\"\n onClick={toggleDrawer}\n >\n <MenuItemLink to=\"\" title={title} icon={icon} tooltip={tooltip} />\n </MenuItem>\n ) : null;\n};\n"],"names":[],"mappings":";;;;;;;AAmCO,MAAM,mBAAmB,CAAC;AAAA,EAC/B,IAAO,GAAA,YAAA;AAAA,EACP,KAAQ,GAAA,aAAA;AAAA,EACR,OAAA;AAAA,EACA;AACF,CAA6B,KAAA;AAC3B,EAAA,MAAM,YAAY,6BAA8B,EAAA;AAChD,EAAM,MAAA,YAAA,GAAe,YAAY,MAAM;AACrC,IAAA,MAAM,YACJ,GAAA,YAAA,CAAa,OAAQ,CAAA,0BAA0B,CAAM,KAAA,MAAA;AACvD,IAAa,YAAA,CAAA,OAAA;AAAA,MACX,0BAAA;AAAA,MACC,CAAA,CAAC,cAAc,QAAS;AAAA,KAC3B;AAAA,GACF,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO,SACL,mBAAA,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAI,EAAE,KAAA,EAAO,QAAQ,KAAO,EAAA,SAAA,EAAW,GAAG,KAAM,EAAA;AAAA,MAChD,aAAY,EAAA,mBAAA;AAAA,MACZ,OAAS,EAAA,YAAA;AAAA,MAET,8BAAC,YAAa,EAAA,EAAA,EAAA,EAAG,EAAG,EAAA,KAAA,EAAc,MAAY,OAAkB,EAAA;AAAA;AAAA,GAEhE,GAAA,IAAA;AACN;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"const.esm.js","sources":["../../../src/components/QuickstartButton/const.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\nexport const QUICKSTART_DRAWER_OPEN_KEY = 'quickstart-drawer-open';\n"],"names":[],"mappings":"AAgBO,MAAM,0BAA6B,GAAA;;;;"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useApi, identityApiRef, configApiRef } from '@backstage/core-plugin-api';
|
|
2
|
+
import { useAsync } from 'react-use';
|
|
3
|
+
|
|
4
|
+
const useQuickstartButtonPermission = () => {
|
|
5
|
+
const identityApi = useApi(identityApiRef);
|
|
6
|
+
const configApi = useApi(configApiRef);
|
|
7
|
+
const getUserAuthorization = async () => {
|
|
8
|
+
const { token: idToken } = await identityApi.getCredentials();
|
|
9
|
+
const backendUrl = configApi.getString("backend.baseUrl");
|
|
10
|
+
const jsonResponse = await fetch(`${backendUrl}/api/permission/`, {
|
|
11
|
+
headers: {
|
|
12
|
+
...idToken && { Authorization: `Bearer ${idToken}` }
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
return jsonResponse.json();
|
|
16
|
+
};
|
|
17
|
+
const { loading: isUserLoading, value: result } = useAsync(
|
|
18
|
+
async () => await getUserAuthorization(),
|
|
19
|
+
[]
|
|
20
|
+
);
|
|
21
|
+
const isRBACPluginEnabled = configApi.getOptionalBoolean("permission.enabled");
|
|
22
|
+
if (!isRBACPluginEnabled) return true;
|
|
23
|
+
return !isUserLoading && result.status === "Authorized";
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { useQuickstartButtonPermission };
|
|
27
|
+
//# sourceMappingURL=useQuickstartButtonPermission.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useQuickstartButtonPermission.esm.js","sources":["../../../src/components/QuickstartButton/useQuickstartButtonPermission.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n configApiRef,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\nimport { useAsync } from 'react-use';\n\nexport const useQuickstartButtonPermission = () => {\n const identityApi = useApi(identityApiRef);\n const configApi = useApi(configApiRef);\n\n const getUserAuthorization = async () => {\n const { token: idToken } = await identityApi.getCredentials();\n const backendUrl = configApi.getString('backend.baseUrl');\n const jsonResponse = await fetch(`${backendUrl}/api/permission/`, {\n headers: {\n ...(idToken && { Authorization: `Bearer ${idToken}` }),\n },\n });\n return jsonResponse.json();\n };\n const { loading: isUserLoading, value: result } = useAsync(\n async () => await getUserAuthorization(),\n [],\n );\n\n const isRBACPluginEnabled =\n configApi.getOptionalBoolean('permission.enabled');\n\n if (!isRBACPluginEnabled) return true;\n\n return !isUserLoading && result.status === 'Authorized';\n};\n"],"names":[],"mappings":";;;AAuBO,MAAM,gCAAgC,MAAM;AACjD,EAAM,MAAA,WAAA,GAAc,OAAO,cAAc,CAAA;AACzC,EAAM,MAAA,SAAA,GAAY,OAAO,YAAY,CAAA;AAErC,EAAA,MAAM,uBAAuB,YAAY;AACvC,IAAA,MAAM,EAAE,KAAO,EAAA,OAAA,EAAY,GAAA,MAAM,YAAY,cAAe,EAAA;AAC5D,IAAM,MAAA,UAAA,GAAa,SAAU,CAAA,SAAA,CAAU,iBAAiB,CAAA;AACxD,IAAA,MAAM,YAAe,GAAA,MAAM,KAAM,CAAA,CAAA,EAAG,UAAU,CAAoB,gBAAA,CAAA,EAAA;AAAA,MAChE,OAAS,EAAA;AAAA,QACP,GAAI,OAAW,IAAA,EAAE,aAAe,EAAA,CAAA,OAAA,EAAU,OAAO,CAAG,CAAA;AAAA;AACtD,KACD,CAAA;AACD,IAAA,OAAO,aAAa,IAAK,EAAA;AAAA,GAC3B;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,aAAe,EAAA,KAAA,EAAO,QAAW,GAAA,QAAA;AAAA,IAChD,YAAY,MAAM,oBAAqB,EAAA;AAAA,IACvC;AAAC,GACH;AAEA,EAAM,MAAA,mBAAA,GACJ,SAAU,CAAA,kBAAA,CAAmB,oBAAoB,CAAA;AAEnD,EAAI,IAAA,CAAC,qBAA4B,OAAA,IAAA;AAEjC,EAAO,OAAA,CAAC,aAAiB,IAAA,MAAA,CAAO,MAAW,KAAA,YAAA;AAC7C;;;;"}
|
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { useApiHolder, configApiRef } from '@backstage/core-plugin-api';
|
|
3
|
-
import { Link
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import Tooltip from '@mui/material/Tooltip';
|
|
7
|
-
import HelpIcon from '@mui/icons-material/HelpOutline';
|
|
3
|
+
import { Link } from '@backstage/core-components';
|
|
4
|
+
import MenuItem from '@mui/material/MenuItem';
|
|
5
|
+
import { MenuItemLink } from '../MenuItemLink/MenuItemLink.esm.js';
|
|
8
6
|
|
|
9
|
-
const Link = (props) => /* @__PURE__ */ jsx(Link$1, { ...props, color: "inherit", externalLinkIcon: false });
|
|
10
7
|
const SupportButton = ({
|
|
11
8
|
title = "Support",
|
|
12
|
-
tooltip,
|
|
13
|
-
color = "inherit",
|
|
14
|
-
size = "small",
|
|
15
9
|
to,
|
|
16
|
-
|
|
10
|
+
icon = "support",
|
|
11
|
+
tooltip,
|
|
12
|
+
style
|
|
17
13
|
}) => {
|
|
18
14
|
const apiHolder = useApiHolder();
|
|
19
15
|
const config = apiHolder.get(configApiRef);
|
|
@@ -21,24 +17,24 @@ const SupportButton = ({
|
|
|
21
17
|
if (!supportUrl) {
|
|
22
18
|
return null;
|
|
23
19
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Tooltip,
|
|
20
|
+
return /* @__PURE__ */ jsx(
|
|
21
|
+
MenuItem,
|
|
27
22
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
to: supportUrl,
|
|
24
|
+
component: Link,
|
|
25
|
+
sx: { width: "100%", color: "inherit", ...style },
|
|
26
|
+
"data-testid": "support-button",
|
|
27
|
+
children: /* @__PURE__ */ jsx(
|
|
28
|
+
MenuItemLink,
|
|
31
29
|
{
|
|
32
|
-
component: Link,
|
|
33
|
-
color,
|
|
34
|
-
size,
|
|
35
30
|
to: supportUrl,
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
title,
|
|
32
|
+
icon,
|
|
33
|
+
tooltip
|
|
38
34
|
}
|
|
39
|
-
)
|
|
35
|
+
)
|
|
40
36
|
}
|
|
41
|
-
)
|
|
37
|
+
);
|
|
42
38
|
};
|
|
43
39
|
|
|
44
40
|
export { SupportButton };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupportButton.esm.js","sources":["../../../src/components/SupportButton/SupportButton.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
|
|
1
|
+
{"version":3,"file":"SupportButton.esm.js","sources":["../../../src/components/SupportButton/SupportButton.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 { configApiRef, useApiHolder } from '@backstage/core-plugin-api';\nimport { Link } from '@backstage/core-components';\nimport MenuItem from '@mui/material/MenuItem';\nimport { MenuItemLink } from '../MenuItemLink/MenuItemLink';\nimport { CSSProperties } from 'react';\n\n/**\n * @public\n */\nexport interface SupportButtonProps {\n icon?: string;\n title?: string;\n to?: string;\n tooltip?: string;\n style?: CSSProperties;\n}\n/**\n * @public\n */\nexport const SupportButton = ({\n title = 'Support',\n to,\n icon = 'support',\n tooltip,\n style,\n}: SupportButtonProps) => {\n const apiHolder = useApiHolder();\n const config = apiHolder.get(configApiRef);\n const supportUrl = to ?? config?.getOptionalString('app.support.url');\n\n if (!supportUrl) {\n return null;\n }\n\n return (\n <MenuItem\n to={supportUrl}\n component={Link}\n sx={{ width: '100%', color: 'inherit', ...style }}\n data-testid=\"support-button\"\n >\n <MenuItemLink\n to={supportUrl}\n title={title}\n icon={icon}\n tooltip={tooltip}\n />\n </MenuItem>\n );\n};\n"],"names":[],"mappings":";;;;;;AAmCO,MAAM,gBAAgB,CAAC;AAAA,EAC5B,KAAQ,GAAA,SAAA;AAAA,EACR,EAAA;AAAA,EACA,IAAO,GAAA,SAAA;AAAA,EACP,OAAA;AAAA,EACA;AACF,CAA0B,KAAA;AACxB,EAAA,MAAM,YAAY,YAAa,EAAA;AAC/B,EAAM,MAAA,MAAA,GAAS,SAAU,CAAA,GAAA,CAAI,YAAY,CAAA;AACzC,EAAA,MAAM,UAAa,GAAA,EAAA,IAAM,MAAQ,EAAA,iBAAA,CAAkB,iBAAiB,CAAA;AAEpE,EAAA,IAAI,CAAC,UAAY,EAAA;AACf,IAAO,OAAA,IAAA;AAAA;AAGT,EACE,uBAAA,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,EAAI,EAAA,UAAA;AAAA,MACJ,SAAW,EAAA,IAAA;AAAA,MACX,IAAI,EAAE,KAAA,EAAO,QAAQ,KAAO,EAAA,SAAA,EAAW,GAAG,KAAM,EAAA;AAAA,MAChD,aAAY,EAAA,gBAAA;AAAA,MAEZ,QAAA,kBAAA,GAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UACC,EAAI,EAAA,UAAA;AAAA,UACJ,KAAA;AAAA,UACA,IAAA;AAAA,UACA;AAAA;AAAA;AACF;AAAA,GACF;AAEJ;;;;"}
|
|
@@ -12,6 +12,8 @@ import { Spacer } from '../components/Spacer/Spacer.esm.js';
|
|
|
12
12
|
import { StarredDropdown } from '../components/HeaderDropdownComponent/StarredDropdown.esm.js';
|
|
13
13
|
import { ApplicationLauncherDropdown } from '../components/HeaderDropdownComponent/ApplicationLauncherDropdown.esm.js';
|
|
14
14
|
import { CompanyLogo } from '../components/CompanyLogo/CompanyLogo.esm.js';
|
|
15
|
+
import { HelpDropdown } from '../components/HeaderDropdownComponent/HelpDropdown.esm.js';
|
|
16
|
+
import { QuickstartButton } from '../components/QuickstartButton/QuickstartButton.esm.js';
|
|
15
17
|
|
|
16
18
|
const defaultGlobalHeaderComponentsMountPoints = [
|
|
17
19
|
{
|
|
@@ -72,7 +74,7 @@ const defaultGlobalHeaderComponentsMountPoints = [
|
|
|
72
74
|
}
|
|
73
75
|
},
|
|
74
76
|
{
|
|
75
|
-
Component:
|
|
77
|
+
Component: HelpDropdown,
|
|
76
78
|
config: {
|
|
77
79
|
priority: 80
|
|
78
80
|
}
|
|
@@ -123,6 +125,16 @@ const defaultProfileDropdownMountPoints = [
|
|
|
123
125
|
}
|
|
124
126
|
}
|
|
125
127
|
},
|
|
128
|
+
{
|
|
129
|
+
Component: MenuItemLink,
|
|
130
|
+
config: {
|
|
131
|
+
priority: 150,
|
|
132
|
+
props: {
|
|
133
|
+
title: "My profile",
|
|
134
|
+
icon: "account"
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
},
|
|
126
138
|
{
|
|
127
139
|
Component: LogoutButton,
|
|
128
140
|
config: {
|
|
@@ -130,6 +142,20 @@ const defaultProfileDropdownMountPoints = [
|
|
|
130
142
|
}
|
|
131
143
|
}
|
|
132
144
|
];
|
|
145
|
+
const defaultHelpDropdownMountPoints = [
|
|
146
|
+
{
|
|
147
|
+
Component: QuickstartButton,
|
|
148
|
+
config: {
|
|
149
|
+
priority: 100
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
Component: SupportButton,
|
|
154
|
+
config: {
|
|
155
|
+
priority: 10
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
];
|
|
133
159
|
const defaultApplicationLauncherDropdownMountPoints = [
|
|
134
160
|
{
|
|
135
161
|
Component: MenuItemLink,
|
|
@@ -157,5 +183,5 @@ const defaultApplicationLauncherDropdownMountPoints = [
|
|
|
157
183
|
}
|
|
158
184
|
];
|
|
159
185
|
|
|
160
|
-
export { defaultApplicationLauncherDropdownMountPoints, defaultCreateDropdownMountPoints, defaultGlobalHeaderComponentsMountPoints, defaultProfileDropdownMountPoints };
|
|
186
|
+
export { defaultApplicationLauncherDropdownMountPoints, defaultCreateDropdownMountPoints, defaultGlobalHeaderComponentsMountPoints, defaultHelpDropdownMountPoints, defaultProfileDropdownMountPoints };
|
|
161
187
|
//# sourceMappingURL=defaultMountPoints.esm.js.map
|