@red-hat-developer-hub/backstage-plugin-global-header 1.15.1 → 1.16.1
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/dist/components/HeaderDropdownComponent/ApplicationLauncherDropdown.esm.js +7 -3
- package/dist/components/HeaderDropdownComponent/ApplicationLauncherDropdown.esm.js.map +1 -1
- package/dist/components/HeaderDropdownComponent/CreateDropdown.esm.js +6 -1
- package/dist/components/HeaderDropdownComponent/CreateDropdown.esm.js.map +1 -1
- package/dist/components/HeaderDropdownComponent/DropdownEmptyState.esm.js +34 -25
- package/dist/components/HeaderDropdownComponent/DropdownEmptyState.esm.js.map +1 -1
- package/dist/components/HeaderDropdownComponent/HelpDropdown.esm.js +7 -3
- package/dist/components/HeaderDropdownComponent/HelpDropdown.esm.js.map +1 -1
- package/dist/components/HeaderDropdownComponent/MenuSection.esm.js +4 -1
- package/dist/components/HeaderDropdownComponent/MenuSection.esm.js.map +1 -1
- package/dist/components/HeaderDropdownComponent/ProfileDropdown.esm.js +8 -4
- package/dist/components/HeaderDropdownComponent/ProfileDropdown.esm.js.map +1 -1
- package/dist/components/HeaderDropdownComponent/RegisterAComponentSection.esm.js +4 -2
- package/dist/components/HeaderDropdownComponent/RegisterAComponentSection.esm.js.map +1 -1
- package/dist/components/HeaderDropdownComponent/SoftwareTemplatesSection.esm.js +6 -4
- package/dist/components/HeaderDropdownComponent/SoftwareTemplatesSection.esm.js.map +1 -1
- package/dist/components/HeaderDropdownComponent/StarredDropdown.esm.js +22 -6
- package/dist/components/HeaderDropdownComponent/StarredDropdown.esm.js.map +1 -1
- package/dist/components/LogoutButton/LogoutButton.esm.js +3 -1
- package/dist/components/LogoutButton/LogoutButton.esm.js.map +1 -1
- package/dist/components/MenuItemLink/MenuItemLink.esm.js +5 -2
- package/dist/components/MenuItemLink/MenuItemLink.esm.js.map +1 -1
- package/dist/components/NotificationBanner.esm.js +6 -2
- package/dist/components/NotificationBanner.esm.js.map +1 -1
- package/dist/components/NotificationButton/NotificationButton.esm.js +6 -3
- package/dist/components/NotificationButton/NotificationButton.esm.js.map +1 -1
- package/dist/components/SearchComponent/SearchBar.esm.js +4 -2
- package/dist/components/SearchComponent/SearchBar.esm.js.map +1 -1
- package/dist/components/SearchComponent/SearchInput.esm.js +23 -19
- package/dist/components/SearchComponent/SearchInput.esm.js.map +1 -1
- package/dist/components/SupportButton/SupportButton.esm.js +5 -2
- package/dist/components/SupportButton/SupportButton.esm.js.map +1 -1
- package/dist/defaultMountPoints/defaultMountPoints.esm.js +7 -7
- package/dist/defaultMountPoints/defaultMountPoints.esm.js.map +1 -1
- package/dist/hooks/useTranslation.esm.js +8 -0
- package/dist/hooks/useTranslation.esm.js.map +1 -0
- package/dist/index.d.ts +49 -1
- package/dist/index.esm.js +2 -0
- package/dist/index.esm.js.map +1 -1
- package/dist/plugin.esm.js +2 -0
- package/dist/plugin.esm.js.map +1 -1
- package/dist/translations/de.esm.js +43 -0
- package/dist/translations/de.esm.js.map +1 -0
- package/dist/translations/es.esm.js +43 -0
- package/dist/translations/es.esm.js.map +1 -0
- package/dist/translations/fr.esm.js +43 -0
- package/dist/translations/fr.esm.js.map +1 -0
- package/dist/translations/index.esm.js +15 -0
- package/dist/translations/index.esm.js.map +1 -0
- package/dist/translations/it.esm.js +43 -0
- package/dist/translations/it.esm.js.map +1 -0
- package/dist/translations/ref.esm.js +63 -0
- package/dist/translations/ref.esm.js.map +1 -0
- 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.16.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 60a37b4: Fixes the global header starred items icon color and visibility:
|
|
8
|
+
|
|
9
|
+
- Changed star icon color to use theme.rhdh.general.starredItemsColor for better visibility and customization
|
|
10
|
+
- Star icon now only appears on hover instead of being always visible
|
|
11
|
+
- Maintains consistent styling with table view starred items across the application
|
|
12
|
+
|
|
13
|
+
## 1.16.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- 6d86c5c: Add internationalization (i18n) support with German, French, Italian, and Spanish translations.
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- cf9f6d0: Fixed dropdown empty state corners by removing the border line
|
|
22
|
+
|
|
3
23
|
## 1.15.1
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
|
@@ -4,12 +4,16 @@ import AppsIcon from '@mui/icons-material/Apps';
|
|
|
4
4
|
import AppRegistrationIcon from '@mui/icons-material/AppRegistration';
|
|
5
5
|
import { useApplicationLauncherDropdownMountPoints } from '../../hooks/useApplicationLauncherDropdownMountPoints.esm.js';
|
|
6
6
|
import { useDropdownManager } from '../../hooks/useDropdownManager.esm.js';
|
|
7
|
+
import { useTranslation } from '../../hooks/useTranslation.esm.js';
|
|
8
|
+
import '@backstage/core-plugin-api';
|
|
9
|
+
import '@backstage/core-plugin-api/alpha';
|
|
7
10
|
import { HeaderDropdownComponent } from './HeaderDropdownComponent.esm.js';
|
|
8
11
|
import { MenuSection } from './MenuSection.esm.js';
|
|
9
12
|
import { DropdownEmptyState } from './DropdownEmptyState.esm.js';
|
|
10
13
|
|
|
11
14
|
const ApplicationLauncherDropdown = () => {
|
|
12
15
|
const { anchorEl, handleOpen, handleClose } = useDropdownManager();
|
|
16
|
+
const { t } = useTranslation();
|
|
13
17
|
const mountPoints = useApplicationLauncherDropdownMountPoints();
|
|
14
18
|
const sectionsObject = useMemo(() => {
|
|
15
19
|
const groupedSections = {};
|
|
@@ -39,7 +43,7 @@ const ApplicationLauncherDropdown = () => {
|
|
|
39
43
|
HeaderDropdownComponent,
|
|
40
44
|
{
|
|
41
45
|
buttonContent: /* @__PURE__ */ jsx(AppsIcon, {}),
|
|
42
|
-
tooltip: "
|
|
46
|
+
tooltip: t("applicationLauncher.tooltip"),
|
|
43
47
|
isIconButton: true,
|
|
44
48
|
onOpen: handleOpen,
|
|
45
49
|
onClose: handleClose,
|
|
@@ -60,8 +64,8 @@ const ApplicationLauncherDropdown = () => {
|
|
|
60
64
|
) : /* @__PURE__ */ jsx(
|
|
61
65
|
DropdownEmptyState,
|
|
62
66
|
{
|
|
63
|
-
title: "
|
|
64
|
-
subTitle: "
|
|
67
|
+
title: t("applicationLauncher.noLinksTitle"),
|
|
68
|
+
subTitle: t("applicationLauncher.noLinksSubtitle"),
|
|
65
69
|
icon: /* @__PURE__ */ jsx(
|
|
66
70
|
AppRegistrationIcon,
|
|
67
71
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApplicationLauncherDropdown.esm.js","sources":["../../../src/components/HeaderDropdownComponent/ApplicationLauncherDropdown.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 { useMemo } from 'react';\n\nimport AppsIcon from '@mui/icons-material/Apps';\nimport AppRegistrationIcon from '@mui/icons-material/AppRegistration';\n\nimport { useApplicationLauncherDropdownMountPoints } from '../../hooks/useApplicationLauncherDropdownMountPoints';\nimport { useDropdownManager } from '../../hooks';\nimport { HeaderDropdownComponent } from './HeaderDropdownComponent';\nimport { MenuSection } from './MenuSection';\nimport { DropdownEmptyState } from './DropdownEmptyState';\n\nexport const ApplicationLauncherDropdown = () => {\n const { anchorEl, handleOpen, handleClose } = useDropdownManager();\n\n const mountPoints = useApplicationLauncherDropdownMountPoints();\n\n const sectionsObject = useMemo(() => {\n const groupedSections: Record<\n string,\n { sectionLink?: string; sectionLinkLabel?: string; items: any[] }\n > = {};\n\n (mountPoints ?? []).forEach(mp => {\n const section = mp.config?.section ?? '';\n const sectionLink = mp.config?.sectionLink ?? '';\n const sectionLinkLabel = mp.config?.sectionLinkLabel ?? '';\n\n if (!groupedSections[section]) {\n groupedSections[section] = { sectionLink, sectionLinkLabel, items: [] };\n }\n groupedSections[section].items.push({\n Component: mp.Component,\n icon: mp.config?.props?.icon,\n label: mp.config?.props?.title,\n link: mp.config?.props?.link,\n external: mp.config?.props?.external ?? false,\n priority: mp.config?.priority ?? 0,\n });\n });\n\n Object.values(groupedSections).forEach(section => {\n section.items.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));\n });\n\n return groupedSections;\n }, [mountPoints]);\n\n const sections = Object.entries(sectionsObject);\n\n return (\n <HeaderDropdownComponent\n buttonContent={<AppsIcon />}\n tooltip
|
|
1
|
+
{"version":3,"file":"ApplicationLauncherDropdown.esm.js","sources":["../../../src/components/HeaderDropdownComponent/ApplicationLauncherDropdown.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 { useMemo } from 'react';\n\nimport AppsIcon from '@mui/icons-material/Apps';\nimport AppRegistrationIcon from '@mui/icons-material/AppRegistration';\n\nimport { useApplicationLauncherDropdownMountPoints } from '../../hooks/useApplicationLauncherDropdownMountPoints';\nimport { useDropdownManager } from '../../hooks';\nimport { HeaderDropdownComponent } from './HeaderDropdownComponent';\nimport { MenuSection } from './MenuSection';\nimport { DropdownEmptyState } from './DropdownEmptyState';\nimport { useTranslation } from '../../hooks/useTranslation';\n\nexport const ApplicationLauncherDropdown = () => {\n const { anchorEl, handleOpen, handleClose } = useDropdownManager();\n const { t } = useTranslation();\n\n const mountPoints = useApplicationLauncherDropdownMountPoints();\n\n const sectionsObject = useMemo(() => {\n const groupedSections: Record<\n string,\n { sectionLink?: string; sectionLinkLabel?: string; items: any[] }\n > = {};\n\n (mountPoints ?? []).forEach(mp => {\n const section = mp.config?.section ?? '';\n const sectionLink = mp.config?.sectionLink ?? '';\n const sectionLinkLabel = mp.config?.sectionLinkLabel ?? '';\n\n if (!groupedSections[section]) {\n groupedSections[section] = { sectionLink, sectionLinkLabel, items: [] };\n }\n groupedSections[section].items.push({\n Component: mp.Component,\n icon: mp.config?.props?.icon,\n label: mp.config?.props?.title,\n link: mp.config?.props?.link,\n external: mp.config?.props?.external ?? false,\n priority: mp.config?.priority ?? 0,\n });\n });\n\n Object.values(groupedSections).forEach(section => {\n section.items.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));\n });\n\n return groupedSections;\n }, [mountPoints]);\n\n const sections = Object.entries(sectionsObject);\n\n return (\n <HeaderDropdownComponent\n buttonContent={<AppsIcon />}\n tooltip={t('applicationLauncher.tooltip')}\n isIconButton\n onOpen={handleOpen}\n onClose={handleClose}\n anchorEl={anchorEl}\n >\n {sections.length > 0 ? (\n sections.map(\n ([section, { sectionLink, sectionLinkLabel, items }], index) => (\n <MenuSection\n key={section}\n sectionLabel={section}\n optionalLink={sectionLink}\n optionalLinkLabel={sectionLinkLabel}\n items={items}\n handleClose={handleClose}\n hideDivider={index === sections.length - 1}\n />\n ),\n )\n ) : (\n <DropdownEmptyState\n title={t('applicationLauncher.noLinksTitle')}\n subTitle={t('applicationLauncher.noLinksSubtitle')}\n icon={\n <AppRegistrationIcon\n sx={{ fontSize: 64, color: 'text.disabled' }}\n />\n }\n />\n )}\n </HeaderDropdownComponent>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -2,11 +2,15 @@ import { jsx, jsxs } from 'react/jsx-runtime';
|
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
3
|
import ArrowDropDownOutlinedIcon from '@mui/icons-material/ArrowDropDownOutlined';
|
|
4
4
|
import { useCreateDropdownMountPoints } from '../../hooks/useCreateDropdownMountPoints.esm.js';
|
|
5
|
+
import { useTranslation } from '../../hooks/useTranslation.esm.js';
|
|
5
6
|
import { useDropdownManager } from '../../hooks/useDropdownManager.esm.js';
|
|
7
|
+
import '@backstage/core-plugin-api';
|
|
8
|
+
import '@backstage/core-plugin-api/alpha';
|
|
6
9
|
import { HeaderDropdownComponent } from './HeaderDropdownComponent.esm.js';
|
|
7
10
|
import Box from '@mui/material/Box';
|
|
8
11
|
|
|
9
12
|
const CreateDropdown = ({ layout }) => {
|
|
13
|
+
const { t } = useTranslation();
|
|
10
14
|
const { anchorEl, handleOpen, handleClose } = useDropdownManager();
|
|
11
15
|
const createDropdownMountPoints = useCreateDropdownMountPoints();
|
|
12
16
|
const menuSections = useMemo(() => {
|
|
@@ -22,7 +26,8 @@ const CreateDropdown = ({ layout }) => {
|
|
|
22
26
|
HeaderDropdownComponent,
|
|
23
27
|
{
|
|
24
28
|
buttonContent: /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center" }, children: [
|
|
25
|
-
"
|
|
29
|
+
t("create.title"),
|
|
30
|
+
" ",
|
|
26
31
|
/* @__PURE__ */ jsx(ArrowDropDownOutlinedIcon, { sx: { ml: 1 } })
|
|
27
32
|
] }),
|
|
28
33
|
buttonProps: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateDropdown.esm.js","sources":["../../../src/components/HeaderDropdownComponent/CreateDropdown.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, ComponentType } from 'react';\n\nimport ArrowDropDownOutlinedIcon from '@mui/icons-material/ArrowDropDownOutlined';\n\nimport { MenuItemConfig } from './MenuSection';\nimport { useCreateDropdownMountPoints } from '../../hooks/useCreateDropdownMountPoints';\nimport { useDropdownManager } from '../../hooks';\nimport { HeaderDropdownComponent } from './HeaderDropdownComponent';\nimport Box from '@mui/material/Box';\n\n/**\n * @public\n * Props for each dropdown section component\n */\ninterface SectionComponentProps {\n handleClose: () => void;\n hideDivider: boolean;\n items?: MenuItemConfig[];\n}\n\n/**\n * @public\n * Props for Create Dropdown\n */\nexport interface CreateDropdownProps {\n layout?: CSSProperties;\n}\n\nexport const CreateDropdown = ({ layout }: CreateDropdownProps) => {\n const { anchorEl, handleOpen, handleClose } = useDropdownManager();\n\n const createDropdownMountPoints = useCreateDropdownMountPoints();\n\n const menuSections = useMemo(() => {\n return (createDropdownMountPoints ?? [])\n .map(mp => ({\n Component: mp.Component as ComponentType<SectionComponentProps>,\n priority: mp.config?.priority ?? 0,\n }))\n .sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));\n }, [createDropdownMountPoints]);\n\n if (menuSections.length === 0) {\n return null;\n }\n\n return (\n <HeaderDropdownComponent\n buttonContent={\n <Box sx={{ display: 'flex', alignItems: 'center' }}>\n
|
|
1
|
+
{"version":3,"file":"CreateDropdown.esm.js","sources":["../../../src/components/HeaderDropdownComponent/CreateDropdown.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, ComponentType } from 'react';\n\nimport ArrowDropDownOutlinedIcon from '@mui/icons-material/ArrowDropDownOutlined';\n\nimport { MenuItemConfig } from './MenuSection';\nimport { useCreateDropdownMountPoints } from '../../hooks/useCreateDropdownMountPoints';\nimport { useTranslation } from '../../hooks/useTranslation';\nimport { useDropdownManager } from '../../hooks';\nimport { HeaderDropdownComponent } from './HeaderDropdownComponent';\nimport Box from '@mui/material/Box';\n\n/**\n * @public\n * Props for each dropdown section component\n */\ninterface SectionComponentProps {\n handleClose: () => void;\n hideDivider: boolean;\n items?: MenuItemConfig[];\n}\n\n/**\n * @public\n * Props for Create Dropdown\n */\nexport interface CreateDropdownProps {\n layout?: CSSProperties;\n}\n\nexport const CreateDropdown = ({ layout }: CreateDropdownProps) => {\n const { t } = useTranslation();\n const { anchorEl, handleOpen, handleClose } = useDropdownManager();\n\n const createDropdownMountPoints = useCreateDropdownMountPoints();\n\n const menuSections = useMemo(() => {\n return (createDropdownMountPoints ?? [])\n .map(mp => ({\n Component: mp.Component as ComponentType<SectionComponentProps>,\n priority: mp.config?.priority ?? 0,\n }))\n .sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));\n }, [createDropdownMountPoints]);\n\n if (menuSections.length === 0) {\n return null;\n }\n\n return (\n <HeaderDropdownComponent\n buttonContent={\n <Box sx={{ display: 'flex', alignItems: 'center' }}>\n {t('create.title')} <ArrowDropDownOutlinedIcon sx={{ ml: 1 }} />\n </Box>\n }\n buttonProps={{\n variant: 'outlined',\n sx: {\n color: 'inherit',\n ...layout,\n },\n }}\n onOpen={handleOpen}\n onClose={handleClose}\n anchorEl={anchorEl}\n >\n {menuSections.map((section, index) => (\n <section.Component\n key={`menu-section-${index.toString()}`}\n hideDivider={index === menuSections.length - 1}\n handleClose={handleClose}\n />\n ))}\n </HeaderDropdownComponent>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;AA8CO,MAAM,cAAiB,GAAA,CAAC,EAAE,MAAA,EAAkC,KAAA;AACjE,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAC7B,EAAA,MAAM,EAAE,QAAA,EAAU,UAAY,EAAA,WAAA,KAAgB,kBAAmB,EAAA;AAEjE,EAAA,MAAM,4BAA4B,4BAA6B,EAAA;AAE/D,EAAM,MAAA,YAAA,GAAe,QAAQ,MAAM;AACjC,IAAA,OAAA,CAAQ,yBAA6B,IAAA,EAClC,EAAA,GAAA,CAAI,CAAO,EAAA,MAAA;AAAA,MACV,WAAW,EAAG,CAAA,SAAA;AAAA,MACd,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,yBAAyB,CAAC,CAAA;AAE9B,EAAI,IAAA,YAAA,CAAa,WAAW,CAAG,EAAA;AAC7B,IAAO,OAAA,IAAA;AAAA;AAGT,EACE,uBAAA,GAAA;AAAA,IAAC,uBAAA;AAAA,IAAA;AAAA,MACC,aAAA,uBACG,GAAI,EAAA,EAAA,EAAA,EAAI,EAAE,OAAS,EAAA,MAAA,EAAQ,UAAY,EAAA,QAAA,EACrC,EAAA,QAAA,EAAA;AAAA,QAAA,CAAA,CAAE,cAAc,CAAA;AAAA,QAAE,GAAA;AAAA,4BAAE,yBAA0B,EAAA,EAAA,EAAA,EAAI,EAAE,EAAA,EAAI,GAAK,EAAA;AAAA,OAChE,EAAA,CAAA;AAAA,MAEF,WAAa,EAAA;AAAA,QACX,OAAS,EAAA,UAAA;AAAA,QACT,EAAI,EAAA;AAAA,UACF,KAAO,EAAA,SAAA;AAAA,UACP,GAAG;AAAA;AACL,OACF;AAAA,MACA,MAAQ,EAAA,UAAA;AAAA,MACR,OAAS,EAAA,WAAA;AAAA,MACT,QAAA;AAAA,MAEC,QAAa,EAAA,YAAA,CAAA,GAAA,CAAI,CAAC,OAAA,EAAS,KAC1B,qBAAA,GAAA;AAAA,QAAC,OAAQ,CAAA,SAAA;AAAA,QAAR;AAAA,UAEC,WAAA,EAAa,KAAU,KAAA,YAAA,CAAa,MAAS,GAAA,CAAA;AAAA,UAC7C;AAAA,SAAA;AAAA,QAFK,CAAA,aAAA,EAAgB,KAAM,CAAA,QAAA,EAAU,CAAA;AAAA,OAIxC;AAAA;AAAA,GACH;AAEJ;;;;"}
|
|
@@ -8,36 +8,45 @@ const DropdownEmptyState = ({
|
|
|
8
8
|
subTitle,
|
|
9
9
|
icon
|
|
10
10
|
}) => {
|
|
11
|
-
return /* @__PURE__ */ jsx(
|
|
11
|
+
return /* @__PURE__ */ jsx(
|
|
12
12
|
Box,
|
|
13
13
|
{
|
|
14
14
|
sx: {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
alignItems: "center",
|
|
18
|
-
justifyContent: "center",
|
|
19
|
-
textAlign: "center",
|
|
20
|
-
py: 4,
|
|
21
|
-
px: 2,
|
|
22
|
-
// Added padding to control width
|
|
23
|
-
maxWidth: 300,
|
|
24
|
-
// Set max width to constrain text expansion
|
|
25
|
-
mx: "auto"
|
|
15
|
+
borderRadius: (theme) => theme.spacing(2.5),
|
|
16
|
+
overflow: "hidden"
|
|
26
17
|
},
|
|
27
|
-
children:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
18
|
+
children: /* @__PURE__ */ jsx(InfoCard, { children: /* @__PURE__ */ jsxs(
|
|
19
|
+
Box,
|
|
20
|
+
{
|
|
21
|
+
sx: {
|
|
22
|
+
display: "flex",
|
|
23
|
+
flexDirection: "column",
|
|
24
|
+
alignItems: "center",
|
|
25
|
+
justifyContent: "center",
|
|
26
|
+
textAlign: "center",
|
|
27
|
+
py: 4,
|
|
28
|
+
px: 2,
|
|
29
|
+
// Added padding to control width
|
|
30
|
+
maxWidth: 300,
|
|
31
|
+
// Set max width to constrain text expansion
|
|
32
|
+
mx: "auto"
|
|
33
|
+
},
|
|
34
|
+
children: [
|
|
35
|
+
icon,
|
|
36
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h6", sx: { mt: 2, color: "text.primary" }, children: title }),
|
|
37
|
+
/* @__PURE__ */ jsx(
|
|
38
|
+
Typography,
|
|
39
|
+
{
|
|
40
|
+
variant: "body2",
|
|
41
|
+
sx: { mt: 1, color: "text.secondary", maxWidth: 250 },
|
|
42
|
+
children: subTitle
|
|
43
|
+
}
|
|
44
|
+
)
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
) })
|
|
39
48
|
}
|
|
40
|
-
)
|
|
49
|
+
);
|
|
41
50
|
};
|
|
42
51
|
|
|
43
52
|
export { DropdownEmptyState };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropdownEmptyState.esm.js","sources":["../../../src/components/HeaderDropdownComponent/DropdownEmptyState.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 { ReactNode, FC } from 'react';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport { InfoCard } from '@backstage/core-components';\n\n/**\n * @public\n * Props for dropdown empty state\n */\ninterface DropdownEmptyStateProps {\n title: string;\n subTitle: string;\n icon: ReactNode;\n}\n\nexport const DropdownEmptyState: FC<DropdownEmptyStateProps> = ({\n title,\n subTitle,\n icon,\n}) => {\n return (\n <
|
|
1
|
+
{"version":3,"file":"DropdownEmptyState.esm.js","sources":["../../../src/components/HeaderDropdownComponent/DropdownEmptyState.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 { ReactNode, FC } from 'react';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport { InfoCard } from '@backstage/core-components';\n\n/**\n * @public\n * Props for dropdown empty state\n */\ninterface DropdownEmptyStateProps {\n title: string;\n subTitle: string;\n icon: ReactNode;\n}\n\nexport const DropdownEmptyState: FC<DropdownEmptyStateProps> = ({\n title,\n subTitle,\n icon,\n}) => {\n return (\n <Box\n sx={{\n borderRadius: theme => theme.spacing(2.5),\n overflow: 'hidden',\n }}\n >\n <InfoCard>\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n textAlign: 'center',\n py: 4,\n px: 2, // Added padding to control width\n maxWidth: 300, // Set max width to constrain text expansion\n mx: 'auto',\n }}\n >\n {icon}\n <Typography variant=\"h6\" sx={{ mt: 2, color: 'text.primary' }}>\n {title}\n </Typography>\n <Typography\n variant=\"body2\"\n sx={{ mt: 1, color: 'text.secondary', maxWidth: 250 }}\n >\n {subTitle}\n </Typography>\n </Box>\n </InfoCard>\n </Box>\n );\n};\n"],"names":[],"mappings":";;;;;AA8BO,MAAM,qBAAkD,CAAC;AAAA,EAC9D,KAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAM,KAAA;AACJ,EACE,uBAAA,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,EAAI,EAAA;AAAA,QACF,YAAc,EAAA,CAAA,KAAA,KAAS,KAAM,CAAA,OAAA,CAAQ,GAAG,CAAA;AAAA,QACxC,QAAU,EAAA;AAAA,OACZ;AAAA,MAEA,8BAAC,QACC,EAAA,EAAA,QAAA,kBAAA,IAAA;AAAA,QAAC,GAAA;AAAA,QAAA;AAAA,UACC,EAAI,EAAA;AAAA,YACF,OAAS,EAAA,MAAA;AAAA,YACT,aAAe,EAAA,QAAA;AAAA,YACf,UAAY,EAAA,QAAA;AAAA,YACZ,cAAgB,EAAA,QAAA;AAAA,YAChB,SAAW,EAAA,QAAA;AAAA,YACX,EAAI,EAAA,CAAA;AAAA,YACJ,EAAI,EAAA,CAAA;AAAA;AAAA,YACJ,QAAU,EAAA,GAAA;AAAA;AAAA,YACV,EAAI,EAAA;AAAA,WACN;AAAA,UAEC,QAAA,EAAA;AAAA,YAAA,IAAA;AAAA,4BACD,GAAA,CAAC,UAAW,EAAA,EAAA,OAAA,EAAQ,IAAK,EAAA,EAAA,EAAI,EAAE,EAAA,EAAI,CAAG,EAAA,KAAA,EAAO,cAAe,EAAA,EACzD,QACH,EAAA,KAAA,EAAA,CAAA;AAAA,4BACA,GAAA;AAAA,cAAC,UAAA;AAAA,cAAA;AAAA,gBACC,OAAQ,EAAA,OAAA;AAAA,gBACR,IAAI,EAAE,EAAA,EAAI,GAAG,KAAO,EAAA,gBAAA,EAAkB,UAAU,GAAI,EAAA;AAAA,gBAEnD,QAAA,EAAA;AAAA;AAAA;AACH;AAAA;AAAA,OAEJ,EAAA;AAAA;AAAA,GACF;AAEJ;;;;"}
|
|
@@ -2,6 +2,9 @@ import { jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import { useMemo, useRef, useEffect } from 'react';
|
|
3
3
|
import { HeaderDropdownComponent } from './HeaderDropdownComponent.esm.js';
|
|
4
4
|
import { useDropdownManager } from '../../hooks/useDropdownManager.esm.js';
|
|
5
|
+
import { useTranslation } from '../../hooks/useTranslation.esm.js';
|
|
6
|
+
import '@backstage/core-plugin-api';
|
|
7
|
+
import '@backstage/core-plugin-api/alpha';
|
|
5
8
|
import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
|
|
6
9
|
import { useHelpDropdownMountPoints } from '../../hooks/useHelpDropdownMountPoints.esm.js';
|
|
7
10
|
import { MenuSection } from './MenuSection.esm.js';
|
|
@@ -43,6 +46,7 @@ const ValidityTracker = ({
|
|
|
43
46
|
const HelpDropdown = ({ layout }) => {
|
|
44
47
|
const { anchorEl, handleOpen, handleClose } = useDropdownManager();
|
|
45
48
|
const helpDropdownMountPoints = useHelpDropdownMountPoints();
|
|
49
|
+
const { t } = useTranslation();
|
|
46
50
|
const { shouldShowEmpty, updateComponentValidity } = useValidComponentTracker(
|
|
47
51
|
helpDropdownMountPoints?.length ?? 0
|
|
48
52
|
);
|
|
@@ -74,7 +78,7 @@ const HelpDropdown = ({ layout }) => {
|
|
|
74
78
|
HeaderDropdownComponent,
|
|
75
79
|
{
|
|
76
80
|
isIconButton: true,
|
|
77
|
-
tooltip: "
|
|
81
|
+
tooltip: t("help.tooltip"),
|
|
78
82
|
buttonContent: /* @__PURE__ */ jsx(HelpOutlineIcon, {}),
|
|
79
83
|
buttonProps: {
|
|
80
84
|
color: "inherit",
|
|
@@ -86,8 +90,8 @@ const HelpDropdown = ({ layout }) => {
|
|
|
86
90
|
children: !shouldShowEmpty ? /* @__PURE__ */ jsx(MenuSection, { hideDivider: true, items: menuItems, handleClose }) : /* @__PURE__ */ jsx(
|
|
87
91
|
DropdownEmptyState,
|
|
88
92
|
{
|
|
89
|
-
title: "
|
|
90
|
-
subTitle: "
|
|
93
|
+
title: t("help.noSupportLinks"),
|
|
94
|
+
subTitle: t("help.noSupportLinksSubtitle"),
|
|
91
95
|
icon: /* @__PURE__ */ jsx(SupportAgentIcon, { sx: { fontSize: 64, color: "text.disabled" } })
|
|
92
96
|
}
|
|
93
97
|
)
|
|
@@ -1 +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 { useEffect, useMemo, useRef } from 'react';\nimport type { ComponentType, 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';\nimport { DropdownEmptyState } from './DropdownEmptyState';\nimport SupportAgentIcon from '@mui/icons-material/SupportAgent';\nimport { useValidComponentTracker } from '../../hooks/useValidComponentTracker';\n\n/**\n * @public\n */\nexport interface HelpDropdownProps {\n layout?: CSSProperties;\n}\n\nconst ValidityTracker = ({\n Component,\n props,\n componentId,\n onValidityChange,\n}: {\n Component: ComponentType<any>;\n props: any;\n componentId: string;\n onValidityChange: (componentId: string, isValid: boolean) => void;\n}) => {\n const contentRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const checkContent = () => {\n if (!contentRef.current) return;\n\n const element = contentRef.current;\n const hasText = (element.textContent?.trim().length ?? 0) > 0;\n const hasChildren = element.children.length > 0;\n const hasChildNodes = element.childNodes.length > 0;\n\n // A component is valid if it renders ANY content at all\n const componentIsValid = hasText || hasChildren || hasChildNodes;\n\n onValidityChange(componentId, componentIsValid);\n };\n\n // Check after component has had time to render (longer timeout for lazy components)\n const timer1 = setTimeout(checkContent, 500);\n const timer2 = setTimeout(checkContent, 1500); // Double check later\n\n return () => {\n clearTimeout(timer1);\n clearTimeout(timer2);\n };\n }, [componentId, onValidityChange]);\n\n try {\n return (\n <div ref={contentRef}>\n <Component {...props} />\n </div>\n );\n } catch (error) {\n onValidityChange(componentId, false);\n return null;\n }\n};\n\nexport const HelpDropdown = ({ layout }: HelpDropdownProps) => {\n const { anchorEl, handleOpen, handleClose } = useDropdownManager();\n const helpDropdownMountPoints = useHelpDropdownMountPoints();\n\n const { shouldShowEmpty, updateComponentValidity } = useValidComponentTracker(\n helpDropdownMountPoints?.length ?? 0,\n );\n\n // Create all mount point items with validity tracking\n const allMenuItems = useMemo(() => {\n return (helpDropdownMountPoints ?? [])\n .map((mp, index) => {\n const componentId = `${mp.config?.props?.title || 'helpItem'}-${\n mp.config?.priority || 0\n }-${index}`;\n\n return {\n componentId,\n Component: () => (\n <ValidityTracker\n Component={mp.Component}\n props={mp.config?.props || {}}\n componentId={componentId}\n onValidityChange={updateComponentValidity}\n />\n ),\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 })\n .sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));\n }, [helpDropdownMountPoints, updateComponentValidity]);\n\n const menuItems = allMenuItems;\n\n return (\n <HeaderDropdownComponent\n isIconButton\n tooltip
|
|
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 { useEffect, useMemo, useRef } from 'react';\nimport type { ComponentType, 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';\nimport { DropdownEmptyState } from './DropdownEmptyState';\nimport SupportAgentIcon from '@mui/icons-material/SupportAgent';\nimport { useValidComponentTracker } from '../../hooks/useValidComponentTracker';\nimport { useTranslation } from '../../hooks/useTranslation';\n\n/**\n * @public\n */\nexport interface HelpDropdownProps {\n layout?: CSSProperties;\n}\n\nconst ValidityTracker = ({\n Component,\n props,\n componentId,\n onValidityChange,\n}: {\n Component: ComponentType<any>;\n props: any;\n componentId: string;\n onValidityChange: (componentId: string, isValid: boolean) => void;\n}) => {\n const contentRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const checkContent = () => {\n if (!contentRef.current) return;\n\n const element = contentRef.current;\n const hasText = (element.textContent?.trim().length ?? 0) > 0;\n const hasChildren = element.children.length > 0;\n const hasChildNodes = element.childNodes.length > 0;\n\n // A component is valid if it renders ANY content at all\n const componentIsValid = hasText || hasChildren || hasChildNodes;\n\n onValidityChange(componentId, componentIsValid);\n };\n\n // Check after component has had time to render (longer timeout for lazy components)\n const timer1 = setTimeout(checkContent, 500);\n const timer2 = setTimeout(checkContent, 1500); // Double check later\n\n return () => {\n clearTimeout(timer1);\n clearTimeout(timer2);\n };\n }, [componentId, onValidityChange]);\n\n try {\n return (\n <div ref={contentRef}>\n <Component {...props} />\n </div>\n );\n } catch (error) {\n onValidityChange(componentId, false);\n return null;\n }\n};\n\nexport const HelpDropdown = ({ layout }: HelpDropdownProps) => {\n const { anchorEl, handleOpen, handleClose } = useDropdownManager();\n const helpDropdownMountPoints = useHelpDropdownMountPoints();\n const { t } = useTranslation();\n\n const { shouldShowEmpty, updateComponentValidity } = useValidComponentTracker(\n helpDropdownMountPoints?.length ?? 0,\n );\n\n // Create all mount point items with validity tracking\n const allMenuItems = useMemo(() => {\n return (helpDropdownMountPoints ?? [])\n .map((mp, index) => {\n const componentId = `${mp.config?.props?.title || 'helpItem'}-${\n mp.config?.priority || 0\n }-${index}`;\n\n return {\n componentId,\n Component: () => (\n <ValidityTracker\n Component={mp.Component}\n props={mp.config?.props || {}}\n componentId={componentId}\n onValidityChange={updateComponentValidity}\n />\n ),\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 })\n .sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));\n }, [helpDropdownMountPoints, updateComponentValidity]);\n\n const menuItems = allMenuItems;\n\n return (\n <HeaderDropdownComponent\n isIconButton\n tooltip={t('help.tooltip')}\n buttonContent={<HelpOutlineIcon />}\n buttonProps={{\n color: 'inherit',\n sx: layout,\n }}\n onOpen={handleOpen}\n onClose={handleClose}\n anchorEl={anchorEl}\n >\n {!shouldShowEmpty ? (\n <MenuSection hideDivider items={menuItems} handleClose={handleClose} />\n ) : (\n <DropdownEmptyState\n title={t('help.noSupportLinks')}\n subTitle={t('help.noSupportLinksSubtitle')}\n icon={\n <SupportAgentIcon sx={{ fontSize: 64, color: 'text.disabled' }} />\n }\n />\n )}\n </HeaderDropdownComponent>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import Box from '@mui/material/Box';
|
|
|
5
5
|
import MenuItem from '@mui/material/MenuItem';
|
|
6
6
|
import { Link } from '@backstage/core-components';
|
|
7
7
|
import ListSubheader from '@mui/material/ListSubheader';
|
|
8
|
+
import { useTranslation } from '../../hooks/useTranslation.esm.js';
|
|
8
9
|
|
|
9
10
|
const MenuSection = ({
|
|
10
11
|
sectionLabel,
|
|
@@ -14,7 +15,9 @@ const MenuSection = ({
|
|
|
14
15
|
hideDivider = false,
|
|
15
16
|
handleClose
|
|
16
17
|
}) => {
|
|
18
|
+
const { t } = useTranslation();
|
|
17
19
|
const hasClickableSubheader = optionalLink && optionalLinkLabel && items.length > 0;
|
|
20
|
+
const translatedSectionLabel = sectionLabel && sectionLabel.includes(".") ? t(sectionLabel, {}) || sectionLabel : sectionLabel;
|
|
18
21
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
19
22
|
sectionLabel && /* @__PURE__ */ jsxs(
|
|
20
23
|
MenuItem,
|
|
@@ -39,7 +42,7 @@ const MenuSection = ({
|
|
|
39
42
|
mt: "0.5rem",
|
|
40
43
|
fontWeight: 400
|
|
41
44
|
},
|
|
42
|
-
children:
|
|
45
|
+
children: translatedSectionLabel
|
|
43
46
|
}
|
|
44
47
|
),
|
|
45
48
|
optionalLinkLabel && /* @__PURE__ */ jsx(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MenuSection.esm.js","sources":["../../../src/components/HeaderDropdownComponent/MenuSection.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 { Fragment } from 'react';\nimport type { ComponentType, FC } from 'react';\nimport Divider from '@mui/material/Divider';\nimport Box from '@mui/material/Box';\nimport MenuItem, { MenuItemProps } from '@mui/material/MenuItem';\nimport { Link } from '@backstage/core-components';\nimport { MenuItemLinkProps } from '../MenuItemLink/MenuItemLink';\nimport ListSubheader from '@mui/material/ListSubheader';\n\n/**\n * Menu item configuration\n *\n * @public\n */\nexport interface MenuItemConfig {\n Component: ComponentType<MenuItemLinkProps | MenuItemProps | {}>;\n label: string;\n icon?: string;\n subLabel?: string;\n link?: string;\n}\n\nexport interface MenuSectionConfig {\n sectionLabel?: string;\n optionalLink?: string;\n optionalLinkLabel?: string;\n items: MenuItemConfig[];\n hideDivider?: boolean;\n handleClose: () => void;\n}\n\nexport const MenuSection: FC<MenuSectionConfig> = ({\n sectionLabel,\n optionalLink,\n optionalLinkLabel,\n items,\n hideDivider = false,\n handleClose,\n}) => {\n const hasClickableSubheader =\n optionalLink && optionalLinkLabel && items.length > 0;\n\n return (\n <>\n {sectionLabel && (\n <MenuItem\n sx={{\n p: 0,\n }}\n disableRipple\n disableTouchRipple\n component={hasClickableSubheader ? Link : Fragment}\n to={optionalLink}\n onClick={handleClose}\n >\n <ListSubheader\n sx={{\n backgroundColor: 'transparent',\n m: 0,\n color: 'text.disabled',\n lineHeight: 2,\n mt: '0.5rem',\n fontWeight: 400,\n }}\n >\n {
|
|
1
|
+
{"version":3,"file":"MenuSection.esm.js","sources":["../../../src/components/HeaderDropdownComponent/MenuSection.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 { Fragment } from 'react';\nimport type { ComponentType, FC } from 'react';\nimport Divider from '@mui/material/Divider';\nimport Box from '@mui/material/Box';\nimport MenuItem, { MenuItemProps } from '@mui/material/MenuItem';\nimport { Link } from '@backstage/core-components';\nimport { MenuItemLinkProps } from '../MenuItemLink/MenuItemLink';\nimport ListSubheader from '@mui/material/ListSubheader';\nimport { useTranslation } from '../../hooks/useTranslation';\n\n/**\n * Menu item configuration\n *\n * @public\n */\nexport interface MenuItemConfig {\n Component: ComponentType<MenuItemLinkProps | MenuItemProps | {}>;\n label: string;\n icon?: string;\n subLabel?: string;\n link?: string;\n}\n\nexport interface MenuSectionConfig {\n sectionLabel?: string;\n optionalLink?: string;\n optionalLinkLabel?: string;\n items: MenuItemConfig[];\n hideDivider?: boolean;\n handleClose: () => void;\n}\n\nexport const MenuSection: FC<MenuSectionConfig> = ({\n sectionLabel,\n optionalLink,\n optionalLinkLabel,\n items,\n hideDivider = false,\n handleClose,\n}) => {\n const { t } = useTranslation();\n const hasClickableSubheader =\n optionalLink && optionalLinkLabel && items.length > 0;\n\n // Check if sectionLabel looks like a translation key (contains dots)\n const translatedSectionLabel =\n sectionLabel && sectionLabel.includes('.')\n ? t(sectionLabel as any, {}) || sectionLabel // Fallback to original if translation fails\n : sectionLabel;\n\n return (\n <>\n {sectionLabel && (\n <MenuItem\n sx={{\n p: 0,\n }}\n disableRipple\n disableTouchRipple\n component={hasClickableSubheader ? Link : Fragment}\n to={optionalLink}\n onClick={handleClose}\n >\n <ListSubheader\n sx={{\n backgroundColor: 'transparent',\n m: 0,\n color: 'text.disabled',\n lineHeight: 2,\n mt: '0.5rem',\n fontWeight: 400,\n }}\n >\n {translatedSectionLabel}\n </ListSubheader>\n\n {optionalLinkLabel && (\n <Box\n sx={{\n fontSize: '0.875em',\n mr: 2,\n flexGrow: 1,\n textAlign: 'right',\n mt: '0.5rem',\n }}\n >\n {optionalLinkLabel}\n </Box>\n )}\n </MenuItem>\n )}\n\n {items.map(({ icon, label, subLabel, link, Component }, index) => (\n <MenuItem\n key={`menu-item-${index.toString()}`}\n disableRipple\n disableTouchRipple\n onClick={handleClose}\n sx={{ py: 0.5 }}\n component={link ? Link : Fragment}\n to={link}\n >\n <Component\n icon={icon}\n to={link!}\n title={label}\n subTitle={subLabel}\n onClick={handleClose}\n />\n </MenuItem>\n ))}\n {!hideDivider && <Divider sx={{ my: 0.5 }} />}\n </>\n );\n};\n"],"names":["Fragment"],"mappings":";;;;;;;;;AAgDO,MAAM,cAAqC,CAAC;AAAA,EACjD,YAAA;AAAA,EACA,YAAA;AAAA,EACA,iBAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAc,GAAA,KAAA;AAAA,EACd;AACF,CAAM,KAAA;AACJ,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAC7B,EAAA,MAAM,qBACJ,GAAA,YAAA,IAAgB,iBAAqB,IAAA,KAAA,CAAM,MAAS,GAAA,CAAA;AAGtD,EAAM,MAAA,sBAAA,GACJ,YAAgB,IAAA,YAAA,CAAa,QAAS,CAAA,GAAG,CACrC,GAAA,CAAA,CAAE,YAAqB,EAAA,EAAE,CAAA,IAAK,YAC9B,GAAA,YAAA;AAEN,EAAA,uBAEK,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,IACC,YAAA,oBAAA,IAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,EAAI,EAAA;AAAA,UACF,CAAG,EAAA;AAAA,SACL;AAAA,QACA,aAAa,EAAA,IAAA;AAAA,QACb,kBAAkB,EAAA,IAAA;AAAA,QAClB,SAAA,EAAW,wBAAwB,IAAOA,GAAAA,UAAAA;AAAA,QAC1C,EAAI,EAAA,YAAA;AAAA,QACJ,OAAS,EAAA,WAAA;AAAA,QAET,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,aAAA;AAAA,YAAA;AAAA,cACC,EAAI,EAAA;AAAA,gBACF,eAAiB,EAAA,aAAA;AAAA,gBACjB,CAAG,EAAA,CAAA;AAAA,gBACH,KAAO,EAAA,eAAA;AAAA,gBACP,UAAY,EAAA,CAAA;AAAA,gBACZ,EAAI,EAAA,QAAA;AAAA,gBACJ,UAAY,EAAA;AAAA,eACd;AAAA,cAEC,QAAA,EAAA;AAAA;AAAA,WACH;AAAA,UAEC,iBACC,oBAAA,GAAA;AAAA,YAAC,GAAA;AAAA,YAAA;AAAA,cACC,EAAI,EAAA;AAAA,gBACF,QAAU,EAAA,SAAA;AAAA,gBACV,EAAI,EAAA,CAAA;AAAA,gBACJ,QAAU,EAAA,CAAA;AAAA,gBACV,SAAW,EAAA,OAAA;AAAA,gBACX,EAAI,EAAA;AAAA,eACN;AAAA,cAEC,QAAA,EAAA;AAAA;AAAA;AACH;AAAA;AAAA,KAEJ;AAAA,IAGD,KAAA,CAAM,GAAI,CAAA,CAAC,EAAE,IAAA,EAAM,OAAO,QAAU,EAAA,IAAA,EAAM,SAAU,EAAA,EAAG,KACtD,qBAAA,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QAEC,aAAa,EAAA,IAAA;AAAA,QACb,kBAAkB,EAAA,IAAA;AAAA,QAClB,OAAS,EAAA,WAAA;AAAA,QACT,EAAA,EAAI,EAAE,EAAA,EAAI,GAAI,EAAA;AAAA,QACd,SAAA,EAAW,OAAO,IAAOA,GAAAA,UAAAA;AAAA,QACzB,EAAI,EAAA,IAAA;AAAA,QAEJ,QAAA,kBAAA,GAAA;AAAA,UAAC,SAAA;AAAA,UAAA;AAAA,YACC,IAAA;AAAA,YACA,EAAI,EAAA,IAAA;AAAA,YACJ,KAAO,EAAA,KAAA;AAAA,YACP,QAAU,EAAA,QAAA;AAAA,YACV,OAAS,EAAA;AAAA;AAAA;AACX,OAAA;AAAA,MAdK,CAAA,UAAA,EAAa,KAAM,CAAA,QAAA,EAAU,CAAA;AAAA,KAgBrC,CAAA;AAAA,IACA,CAAC,+BAAgB,GAAA,CAAA,OAAA,EAAA,EAAQ,IAAI,EAAE,EAAA,EAAI,KAAO,EAAA;AAAA,GAC7C,EAAA,CAAA;AAEJ;;;;"}
|
|
@@ -14,11 +14,14 @@ import { MenuSection } from './MenuSection.esm.js';
|
|
|
14
14
|
import { HeaderDropdownComponent } from './HeaderDropdownComponent.esm.js';
|
|
15
15
|
import { useProfileDropdownMountPoints } from '../../hooks/useProfileDropdownMountPoints.esm.js';
|
|
16
16
|
import { useDropdownManager } from '../../hooks/useDropdownManager.esm.js';
|
|
17
|
+
import { useTranslation } from '../../hooks/useTranslation.esm.js';
|
|
18
|
+
import '@backstage/core-plugin-api/alpha';
|
|
17
19
|
|
|
18
20
|
const ProfileDropdown = ({ layout }) => {
|
|
19
21
|
const { anchorEl, handleOpen, handleClose } = useDropdownManager();
|
|
20
22
|
const [user, setUser] = useState();
|
|
21
23
|
const [profileLink, setProfileLink] = useState();
|
|
24
|
+
const { t } = useTranslation();
|
|
22
25
|
const {
|
|
23
26
|
displayName,
|
|
24
27
|
backstageIdentity,
|
|
@@ -79,20 +82,21 @@ const ProfileDropdown = ({ layout }) => {
|
|
|
79
82
|
icon = "",
|
|
80
83
|
link: staticLink = ""
|
|
81
84
|
} = mp.config?.props ?? {};
|
|
82
|
-
const isMyProfile = title
|
|
85
|
+
const isMyProfile = title === "profile.myProfile";
|
|
83
86
|
const link = isMyProfile ? profileLink ?? "" : staticLink;
|
|
84
87
|
if (!link && title) {
|
|
85
88
|
return null;
|
|
86
89
|
}
|
|
90
|
+
const translatedTitle = title && title.includes(".") ? t(title, {}) || title : title;
|
|
87
91
|
return {
|
|
88
92
|
Component: mp.Component,
|
|
89
|
-
label:
|
|
93
|
+
label: translatedTitle,
|
|
90
94
|
link,
|
|
91
95
|
priority: mp.config?.priority ?? 0,
|
|
92
96
|
...icon && { icon }
|
|
93
97
|
};
|
|
94
98
|
}).filter((item) => item !== null).sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
95
|
-
}, [profileDropdownMountPoints, profileLink]);
|
|
99
|
+
}, [profileDropdownMountPoints, profileLink, t]);
|
|
96
100
|
if (menuItems.length === 0) {
|
|
97
101
|
return null;
|
|
98
102
|
}
|
|
@@ -114,7 +118,7 @@ const ProfileDropdown = ({ layout }) => {
|
|
|
114
118
|
{
|
|
115
119
|
src: profile.picture,
|
|
116
120
|
sx: { mr: 2, height: "32px", width: "32px" },
|
|
117
|
-
alt: "
|
|
121
|
+
alt: t("profile.picture")
|
|
118
122
|
}
|
|
119
123
|
) : /* @__PURE__ */ jsx(AccountCircleOutlinedIcon, { fontSize: "small", sx: { mr: 1 } }),
|
|
120
124
|
/* @__PURE__ */ jsx(
|
|
@@ -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 { 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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"}
|
|
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';\nimport { useTranslation } from '../../hooks/useTranslation';\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 { t } = useTranslation();\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 === 'profile.myProfile';\n const link = isMyProfile ? profileLink ?? '' : staticLink;\n\n if (!link && title) {\n return null;\n }\n\n // Check if title looks like a translation key (contains dots)\n const translatedTitle =\n title && title.includes('.')\n ? t(title as any, {}) || title // Fallback to original title if translation fails\n : title;\n\n return {\n Component: mp.Component,\n label: translatedTitle,\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, t]);\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={t('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,19 +1,21 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { MenuSection } from './MenuSection.esm.js';
|
|
3
3
|
import { MenuItemLink } from '../MenuItemLink/MenuItemLink.esm.js';
|
|
4
|
+
import { useTranslation } from '../../hooks/useTranslation.esm.js';
|
|
4
5
|
|
|
5
6
|
const RegisterAComponentSection = ({
|
|
6
7
|
hideDivider,
|
|
7
8
|
handleClose
|
|
8
9
|
}) => {
|
|
10
|
+
const { t } = useTranslation();
|
|
9
11
|
return /* @__PURE__ */ jsx(
|
|
10
12
|
MenuSection,
|
|
11
13
|
{
|
|
12
14
|
hideDivider,
|
|
13
15
|
items: [
|
|
14
16
|
{
|
|
15
|
-
label: "
|
|
16
|
-
subLabel: "
|
|
17
|
+
label: t("create.registerComponent.title"),
|
|
18
|
+
subLabel: t("create.registerComponent.subtitle"),
|
|
17
19
|
link: "/catalog-import",
|
|
18
20
|
icon: "category",
|
|
19
21
|
Component: MenuItemLink
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RegisterAComponentSection.esm.js","sources":["../../../src/components/HeaderDropdownComponent/RegisterAComponentSection.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 { ComponentType } from 'react';\nimport { MenuSection } from './MenuSection';\nimport { MenuItemLink } from '../MenuItemLink/MenuItemLink';\n\n/**\n * Register A Component Section properties\n *\n * @public\n */\nexport type RegisterAComponentSectionProps = {\n hideDivider: boolean;\n handleClose: () => void;\n};\n\nexport const RegisterAComponentSection = ({\n hideDivider,\n handleClose,\n}: RegisterAComponentSectionProps) => {\n return (\n <MenuSection\n hideDivider={hideDivider}\n items={[\n {\n label: '
|
|
1
|
+
{"version":3,"file":"RegisterAComponentSection.esm.js","sources":["../../../src/components/HeaderDropdownComponent/RegisterAComponentSection.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 { ComponentType } from 'react';\nimport { MenuSection } from './MenuSection';\nimport { MenuItemLink } from '../MenuItemLink/MenuItemLink';\nimport { useTranslation } from '../../hooks/useTranslation';\n\n/**\n * Register A Component Section properties\n *\n * @public\n */\nexport type RegisterAComponentSectionProps = {\n hideDivider: boolean;\n handleClose: () => void;\n};\n\nexport const RegisterAComponentSection = ({\n hideDivider,\n handleClose,\n}: RegisterAComponentSectionProps) => {\n const { t } = useTranslation();\n\n return (\n <MenuSection\n hideDivider={hideDivider}\n items={[\n {\n label: t('create.registerComponent.title'),\n subLabel: t('create.registerComponent.subtitle'),\n link: '/catalog-import',\n icon: 'category',\n Component: MenuItemLink as ComponentType,\n },\n ]}\n handleClose={handleClose}\n />\n );\n};\n"],"names":[],"mappings":";;;;;AA8BO,MAAM,4BAA4B,CAAC;AAAA,EACxC,WAAA;AAAA,EACA;AACF,CAAsC,KAAA;AACpC,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAE7B,EACE,uBAAA,GAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,WAAA;AAAA,MACA,KAAO,EAAA;AAAA,QACL;AAAA,UACE,KAAA,EAAO,EAAE,gCAAgC,CAAA;AAAA,UACzC,QAAA,EAAU,EAAE,mCAAmC,CAAA;AAAA,UAC/C,IAAM,EAAA,iBAAA;AAAA,UACN,IAAM,EAAA,UAAA;AAAA,UACN,SAAW,EAAA;AAAA;AACb,OACF;AAAA,MACA;AAAA;AAAA,GACF;AAEJ;;;;"}
|
|
@@ -7,12 +7,14 @@ import Divider from '@mui/material/Divider';
|
|
|
7
7
|
import Typography from '@mui/material/Typography';
|
|
8
8
|
import { MenuSection } from './MenuSection.esm.js';
|
|
9
9
|
import { MenuItemLink } from '../MenuItemLink/MenuItemLink.esm.js';
|
|
10
|
+
import { useTranslation } from '../../hooks/useTranslation.esm.js';
|
|
10
11
|
|
|
11
12
|
const SoftwareTemplatesSection = ({
|
|
12
13
|
handleClose,
|
|
13
14
|
hideDivider
|
|
14
15
|
}) => {
|
|
15
16
|
const catalogApi = useApi(catalogApiRef);
|
|
17
|
+
const { t } = useTranslation();
|
|
16
18
|
const [entities, setEntities] = useState([]);
|
|
17
19
|
const [_loading, setLoading] = useState(true);
|
|
18
20
|
const [error, setError] = useState(null);
|
|
@@ -40,7 +42,7 @@ const SoftwareTemplatesSection = ({
|
|
|
40
42
|
}));
|
|
41
43
|
}, [entities]);
|
|
42
44
|
if (error) {
|
|
43
|
-
return /* @__PURE__ */ jsx(Box, { display: "flex", justifyContent: "center", alignItems: "center", p: 2, children: /* @__PURE__ */ jsx(Typography, { variant: "body1", color: "error", children: "
|
|
45
|
+
return /* @__PURE__ */ jsx(Box, { display: "flex", justifyContent: "center", alignItems: "center", p: 2, children: /* @__PURE__ */ jsx(Typography, { variant: "body1", color: "error", children: t("create.templates.errorFetching") }) });
|
|
44
46
|
}
|
|
45
47
|
if (items.length === 0) {
|
|
46
48
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -49,7 +51,7 @@ const SoftwareTemplatesSection = ({
|
|
|
49
51
|
{
|
|
50
52
|
variant: "body2",
|
|
51
53
|
sx: { mx: 2, my: 1, color: "text.disabled" },
|
|
52
|
-
children: "
|
|
54
|
+
children: t("create.templates.noTemplatesAvailable")
|
|
53
55
|
}
|
|
54
56
|
),
|
|
55
57
|
!hideDivider && /* @__PURE__ */ jsx(Divider, { sx: { my: 0.5 } })
|
|
@@ -59,9 +61,9 @@ const SoftwareTemplatesSection = ({
|
|
|
59
61
|
MenuSection,
|
|
60
62
|
{
|
|
61
63
|
hideDivider,
|
|
62
|
-
sectionLabel: "
|
|
64
|
+
sectionLabel: t("create.templates.sectionTitle"),
|
|
63
65
|
optionalLink: "/create",
|
|
64
|
-
optionalLinkLabel: "
|
|
66
|
+
optionalLinkLabel: t("create.templates.allTemplates"),
|
|
65
67
|
items,
|
|
66
68
|
handleClose
|
|
67
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SoftwareTemplatesSection.esm.js","sources":["../../../src/components/HeaderDropdownComponent/SoftwareTemplatesSection.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, useState } from 'react';\nimport type { ComponentType } from 'react';\n\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport { Entity } from '@backstage/catalog-model';\n\nimport Box from '@mui/material/Box';\nimport Divider from '@mui/material/Divider';\nimport Typography from '@mui/material/Typography';\n\nimport { MenuSection } from './MenuSection';\nimport { MenuItemLink } from '../MenuItemLink/MenuItemLink';\n\n/**\n * Software Templates Section properties\n *\n * @public\n */\nexport type SoftwareTemplatesSectionProps = {\n handleClose: () => void;\n hideDivider?: boolean;\n};\n\nexport const SoftwareTemplatesSection = ({\n handleClose,\n hideDivider,\n}: SoftwareTemplatesSectionProps) => {\n const catalogApi = useApi(catalogApiRef);\n\n const [entities, setEntities] = useState<Entity[]>([]);\n // TODO: handle loading\n const [_loading, setLoading] = useState(true);\n const [error, setError] = useState(null);\n\n useEffect(() => {\n const fetchEntities = async () => {\n try {\n const response = await catalogApi.getEntities({\n filter: { kind: ['Template'] },\n limit: 7,\n });\n setEntities(response.items);\n } catch (err) {\n setError(err);\n } finally {\n setLoading(false);\n }\n };\n\n fetchEntities();\n }, [catalogApi]);\n\n const items = useMemo(() => {\n return entities\n .filter(e => e.kind === 'Template')\n .map(m => ({\n Component: MenuItemLink as ComponentType,\n label: m.metadata.title ?? m.metadata.name,\n link: `/create/templates/default/${m.metadata.name}`,\n }));\n }, [entities]);\n\n if (error) {\n return (\n <Box display=\"flex\" justifyContent=\"center\" alignItems=\"center\" p={2}>\n <Typography variant=\"body1\" color=\"error\">\n
|
|
1
|
+
{"version":3,"file":"SoftwareTemplatesSection.esm.js","sources":["../../../src/components/HeaderDropdownComponent/SoftwareTemplatesSection.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, useState } from 'react';\nimport type { ComponentType } from 'react';\n\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\nimport { Entity } from '@backstage/catalog-model';\n\nimport Box from '@mui/material/Box';\nimport Divider from '@mui/material/Divider';\nimport Typography from '@mui/material/Typography';\n\nimport { MenuSection } from './MenuSection';\nimport { MenuItemLink } from '../MenuItemLink/MenuItemLink';\nimport { useTranslation } from '../../hooks/useTranslation';\n\n/**\n * Software Templates Section properties\n *\n * @public\n */\nexport type SoftwareTemplatesSectionProps = {\n handleClose: () => void;\n hideDivider?: boolean;\n};\n\nexport const SoftwareTemplatesSection = ({\n handleClose,\n hideDivider,\n}: SoftwareTemplatesSectionProps) => {\n const catalogApi = useApi(catalogApiRef);\n const { t } = useTranslation();\n\n const [entities, setEntities] = useState<Entity[]>([]);\n // TODO: handle loading\n const [_loading, setLoading] = useState(true);\n const [error, setError] = useState(null);\n\n useEffect(() => {\n const fetchEntities = async () => {\n try {\n const response = await catalogApi.getEntities({\n filter: { kind: ['Template'] },\n limit: 7,\n });\n setEntities(response.items);\n } catch (err) {\n setError(err);\n } finally {\n setLoading(false);\n }\n };\n\n fetchEntities();\n }, [catalogApi]);\n\n const items = useMemo(() => {\n return entities\n .filter(e => e.kind === 'Template')\n .map(m => ({\n Component: MenuItemLink as ComponentType,\n label: m.metadata.title ?? m.metadata.name,\n link: `/create/templates/default/${m.metadata.name}`,\n }));\n }, [entities]);\n\n if (error) {\n return (\n <Box display=\"flex\" justifyContent=\"center\" alignItems=\"center\" p={2}>\n <Typography variant=\"body1\" color=\"error\">\n {t('create.templates.errorFetching')}\n </Typography>\n </Box>\n );\n }\n\n if (items.length === 0) {\n return (\n <>\n <Typography\n variant=\"body2\"\n sx={{ mx: 2, my: 1, color: 'text.disabled' }}\n >\n {t('create.templates.noTemplatesAvailable')}\n </Typography>\n {!hideDivider && <Divider sx={{ my: 0.5 }} />}\n </>\n );\n }\n return (\n <MenuSection\n hideDivider={hideDivider}\n sectionLabel={t('create.templates.sectionTitle')}\n optionalLink=\"/create\"\n optionalLinkLabel={t('create.templates.allTemplates')}\n items={items}\n handleClose={handleClose}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;AAyCO,MAAM,2BAA2B,CAAC;AAAA,EACvC,WAAA;AAAA,EACA;AACF,CAAqC,KAAA;AACnC,EAAM,MAAA,UAAA,GAAa,OAAO,aAAa,CAAA;AACvC,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAE7B,EAAA,MAAM,CAAC,QAAU,EAAA,WAAW,CAAI,GAAA,QAAA,CAAmB,EAAE,CAAA;AAErD,EAAA,MAAM,CAAC,QAAA,EAAU,UAAU,CAAA,GAAI,SAAS,IAAI,CAAA;AAC5C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,IAAI,CAAA;AAEvC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,gBAAgB,YAAY;AAChC,MAAI,IAAA;AACF,QAAM,MAAA,QAAA,GAAW,MAAM,UAAA,CAAW,WAAY,CAAA;AAAA,UAC5C,MAAQ,EAAA,EAAE,IAAM,EAAA,CAAC,UAAU,CAAE,EAAA;AAAA,UAC7B,KAAO,EAAA;AAAA,SACR,CAAA;AACD,QAAA,WAAA,CAAY,SAAS,KAAK,CAAA;AAAA,eACnB,GAAK,EAAA;AACZ,QAAA,QAAA,CAAS,GAAG,CAAA;AAAA,OACZ,SAAA;AACA,QAAA,UAAA,CAAW,KAAK,CAAA;AAAA;AAClB,KACF;AAEA,IAAc,aAAA,EAAA;AAAA,GAChB,EAAG,CAAC,UAAU,CAAC,CAAA;AAEf,EAAM,MAAA,KAAA,GAAQ,QAAQ,MAAM;AAC1B,IAAO,OAAA,QAAA,CACJ,OAAO,CAAK,CAAA,KAAA,CAAA,CAAE,SAAS,UAAU,CAAA,CACjC,IAAI,CAAM,CAAA,MAAA;AAAA,MACT,SAAW,EAAA,YAAA;AAAA,MACX,KAAO,EAAA,CAAA,CAAE,QAAS,CAAA,KAAA,IAAS,EAAE,QAAS,CAAA,IAAA;AAAA,MACtC,IAAM,EAAA,CAAA,0BAAA,EAA6B,CAAE,CAAA,QAAA,CAAS,IAAI,CAAA;AAAA,KAClD,CAAA,CAAA;AAAA,GACN,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,IAAI,KAAO,EAAA;AACT,IAAA,2BACG,GAAI,EAAA,EAAA,OAAA,EAAQ,QAAO,cAAe,EAAA,QAAA,EAAS,YAAW,QAAS,EAAA,CAAA,EAAG,GACjE,QAAC,kBAAA,GAAA,CAAA,UAAA,EAAA,EAAW,SAAQ,OAAQ,EAAA,KAAA,EAAM,SAC/B,QAAE,EAAA,CAAA,CAAA,gCAAgC,GACrC,CACF,EAAA,CAAA;AAAA;AAIJ,EAAI,IAAA,KAAA,CAAM,WAAW,CAAG,EAAA;AACtB,IAAA,uBAEI,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,OAAQ,EAAA,OAAA;AAAA,UACR,IAAI,EAAE,EAAA,EAAI,GAAG,EAAI,EAAA,CAAA,EAAG,OAAO,eAAgB,EAAA;AAAA,UAE1C,YAAE,uCAAuC;AAAA;AAAA,OAC5C;AAAA,MACC,CAAC,+BAAgB,GAAA,CAAA,OAAA,EAAA,EAAQ,IAAI,EAAE,EAAA,EAAI,KAAO,EAAA;AAAA,KAC7C,EAAA,CAAA;AAAA;AAGJ,EACE,uBAAA,GAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,WAAA;AAAA,MACA,YAAA,EAAc,EAAE,+BAA+B,CAAA;AAAA,MAC/C,YAAa,EAAA,SAAA;AAAA,MACb,iBAAA,EAAmB,EAAE,+BAA+B,CAAA;AAAA,MACpD,KAAA;AAAA,MACA;AAAA;AAAA,GACF;AAEJ;;;;"}
|