@red-hat-developer-hub/backstage-plugin-quickstart 1.8.1 → 1.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @red-hat-developer-hub/backstage-plugin-quickstart
2
2
 
3
+ ## 1.8.2
4
+
5
+ ### Patch Changes
6
+
7
+ - bb8ef80: Added drawer state management utilities for integration with application drawers.
8
+
3
9
  ## 1.8.1
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -13,6 +13,41 @@ The Quickstart plugin provides a guided onboarding experience for new users of R
13
13
 
14
14
  ## Installation
15
15
 
16
+ ### Installing as a dynamic plugin
17
+
18
+ If you want to install the plugin as a dynamic plugin in Red Hat Developer Hub:
19
+
20
+ - Follow the [Installing plugins guide](https://github.com/redhat-developer/rhdh/blob/main/docs/dynamic-plugins/installing-plugins.md)
21
+ - Add the content of `app-config.dynamic.yaml` into your `app-config.local.yaml`
22
+
23
+ #### Dynamic plugin configuration
24
+
25
+ Add the extension point inside your `app-config.yaml` or `app-config.local.yaml` file:
26
+
27
+ ```yaml
28
+ dynamicPlugins:
29
+ frontend:
30
+ red-hat-developer-hub.backstage-plugin-quickstart:
31
+ translationResources:
32
+ - importName: quickstartTranslations
33
+ ref: quickstartTranslationRef
34
+ mountPoints:
35
+ - mountPoint: application/provider
36
+ importName: QuickstartDrawerProvider
37
+ - mountPoint: application/drawer-state
38
+ importName: QuickstartDrawerStateExposer
39
+ - mountPoint: application/drawer-content
40
+ importName: QuickstartDrawerContent
41
+ config:
42
+ id: quickstart
43
+ - mountPoint: global.header/help
44
+ importName: QuickstartButton
45
+ config:
46
+ priority: 100
47
+ ```
48
+
49
+ ### Static Installation
50
+
16
51
  1. Install the plugin package:
17
52
 
18
53
  ```bash
@@ -1,9 +1,18 @@
1
1
  dynamicPlugins:
2
2
  frontend:
3
3
  red-hat-developer-hub.backstage-plugin-quickstart:
4
+ translationResources:
5
+ - importName: quickstartTranslations
6
+ ref: quickstartTranslationRef
4
7
  mountPoints:
5
8
  - mountPoint: application/provider
6
9
  importName: QuickstartDrawerProvider
10
+ - mountPoint: application/drawer-state
11
+ importName: QuickstartDrawerStateExposer
12
+ - mountPoint: application/drawer-content
13
+ importName: QuickstartDrawerContent
14
+ config:
15
+ id: quickstart
7
16
  - mountPoint: global.header/help
8
17
  importName: QuickstartButton
9
18
  config:
@@ -0,0 +1,37 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useMemo } from 'react';
3
+ import { useApi, configApiRef } from '@backstage/core-plugin-api';
4
+ import { Quickstart } from './Quickstart.esm.js';
5
+ import { useQuickstartDrawerContext } from '../hooks/useQuickstartDrawerContext.esm.js';
6
+ import { filterQuickstartItemsByRole } from '../utils/filterQuickstartItems.esm.js';
7
+
8
+ const QuickstartDrawerContent = () => {
9
+ const { isDrawerOpen, closeDrawer, userRole, roleLoading } = useQuickstartDrawerContext();
10
+ const config = useApi(configApiRef);
11
+ const quickstartItems = useMemo(() => {
12
+ return config?.has("app.quickstart") ? config.get("app.quickstart") : [];
13
+ }, [config]);
14
+ const eligibleItems = useMemo(() => {
15
+ return !roleLoading && userRole ? filterQuickstartItemsByRole(quickstartItems, userRole) : [];
16
+ }, [roleLoading, userRole, quickstartItems]);
17
+ const filteredItems = useMemo(() => {
18
+ return isDrawerOpen ? eligibleItems : [];
19
+ }, [isDrawerOpen, eligibleItems]);
20
+ if (quickstartItems.length === 0) {
21
+ return null;
22
+ }
23
+ if (!roleLoading && eligibleItems.length === 0) {
24
+ return null;
25
+ }
26
+ return /* @__PURE__ */ jsx(
27
+ Quickstart,
28
+ {
29
+ quickstartItems: filteredItems,
30
+ handleDrawerClose: closeDrawer,
31
+ isLoading: roleLoading
32
+ }
33
+ );
34
+ };
35
+
36
+ export { QuickstartDrawerContent };
37
+ //# sourceMappingURL=QuickstartDrawerContent.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuickstartDrawerContent.esm.js","sources":["../../src/components/QuickstartDrawerContent.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 { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport { Quickstart } from './Quickstart';\nimport { useQuickstartDrawerContext } from '../hooks/useQuickstartDrawerContext';\nimport { QuickstartItemData } from '../types';\nimport { filterQuickstartItemsByRole } from '../utils';\n\nexport const QuickstartDrawerContent = () => {\n const { isDrawerOpen, closeDrawer, userRole, roleLoading } =\n useQuickstartDrawerContext();\n\n const config = useApi(configApiRef);\n const quickstartItems: QuickstartItemData[] = useMemo(() => {\n return config?.has('app.quickstart')\n ? (config.get('app.quickstart') as QuickstartItemData[])\n : [];\n }, [config]);\n\n // Items available to the user based on role from context\n const eligibleItems = useMemo(() => {\n return !roleLoading && userRole\n ? filterQuickstartItemsByRole(quickstartItems, userRole)\n : [];\n }, [roleLoading, userRole, quickstartItems]);\n\n // Only expose items to the body when drawer is open to avoid re-renders during close\n const filteredItems = useMemo(() => {\n return isDrawerOpen ? eligibleItems : [];\n }, [isDrawerOpen, eligibleItems]);\n\n // No auto-open logic here; the provider initializes per user (visited/open)\n\n // If no quickstart items are configured at all, don't render the drawer to avoid reserving space\n if (quickstartItems.length === 0) {\n return null;\n }\n\n // If there are no items for the user, hide the drawer entirely\n if (!roleLoading && eligibleItems.length === 0) {\n return null;\n }\n\n // No role-fetching or filtering here when the drawer is closed\n\n return (\n <Quickstart\n quickstartItems={filteredItems}\n handleDrawerClose={closeDrawer}\n isLoading={roleLoading}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;AAuBO,MAAM,0BAA0B,MAAM;AAC3C,EAAA,MAAM,EAAE,YAAc,EAAA,WAAA,EAAa,QAAU,EAAA,WAAA,KAC3C,0BAA2B,EAAA;AAE7B,EAAM,MAAA,MAAA,GAAS,OAAO,YAAY,CAAA;AAClC,EAAM,MAAA,eAAA,GAAwC,QAAQ,MAAM;AAC1D,IAAO,OAAA,MAAA,EAAQ,IAAI,gBAAgB,CAAA,GAC9B,OAAO,GAAI,CAAA,gBAAgB,IAC5B,EAAC;AAAA,GACP,EAAG,CAAC,MAAM,CAAC,CAAA;AAGX,EAAM,MAAA,aAAA,GAAgB,QAAQ,MAAM;AAClC,IAAA,OAAO,CAAC,WAAe,IAAA,QAAA,GACnB,4BAA4B,eAAiB,EAAA,QAAQ,IACrD,EAAC;AAAA,GACJ,EAAA,CAAC,WAAa,EAAA,QAAA,EAAU,eAAe,CAAC,CAAA;AAG3C,EAAM,MAAA,aAAA,GAAgB,QAAQ,MAAM;AAClC,IAAO,OAAA,YAAA,GAAe,gBAAgB,EAAC;AAAA,GACtC,EAAA,CAAC,YAAc,EAAA,aAAa,CAAC,CAAA;AAKhC,EAAI,IAAA,eAAA,CAAgB,WAAW,CAAG,EAAA;AAChC,IAAO,OAAA,IAAA;AAAA;AAIT,EAAA,IAAI,CAAC,WAAA,IAAe,aAAc,CAAA,MAAA,KAAW,CAAG,EAAA;AAC9C,IAAO,OAAA,IAAA;AAAA;AAKT,EACE,uBAAA,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,eAAiB,EAAA,aAAA;AAAA,MACjB,iBAAmB,EAAA,WAAA;AAAA,MACnB,SAAW,EAAA;AAAA;AAAA,GACb;AAEJ;;;;"}
@@ -5,7 +5,6 @@ import Snackbar from '@mui/material/Snackbar';
5
5
  import CloseIcon from '@mui/icons-material/Close';
6
6
  import IconButton from '@mui/material/IconButton';
7
7
  import { QuickstartDrawerContext } from './QuickstartDrawerContext.esm.js';
8
- import { QuickstartDrawer } from './QuickstartDrawer.esm.js';
9
8
  import { filterQuickstartItemsByRole } from '../utils/filterQuickstartItems.esm.js';
10
9
  import { useQuickstartRole } from '../hooks/useQuickstartRole.esm.js';
11
10
 
@@ -18,22 +17,6 @@ const QuickstartDrawerProvider = ({ children }) => {
18
17
  const identityApi = useApi(identityApiRef);
19
18
  const configApi = useApi(configApiRef);
20
19
  const { isLoading: roleLoading, userRole } = useQuickstartRole();
21
- useEffect(() => {
22
- if (isDrawerOpen) {
23
- document.body.classList.add("quickstart-drawer-open");
24
- document.body.style.setProperty(
25
- "--quickstart-drawer-width",
26
- `${drawerWidth}px`
27
- );
28
- } else {
29
- document.body.classList.remove("quickstart-drawer-open");
30
- document.body.style.removeProperty("--quickstart-drawer-width");
31
- }
32
- return () => {
33
- document.body.classList.remove("quickstart-drawer-open");
34
- document.body.style.removeProperty("--quickstart-drawer-width");
35
- };
36
- }, [isDrawerOpen, drawerWidth]);
37
20
  useEffect(() => {
38
21
  let cancelled = false;
39
22
  (async () => {
@@ -135,7 +118,6 @@ const QuickstartDrawerProvider = ({ children }) => {
135
118
  },
136
119
  children: [
137
120
  children,
138
- /* @__PURE__ */ jsx(QuickstartDrawer, {}),
139
121
  /* @__PURE__ */ jsx(
140
122
  Snackbar,
141
123
  {
@@ -1 +1 @@
1
- {"version":3,"file":"QuickstartDrawerProvider.esm.js","sources":["../../src/components/QuickstartDrawerProvider.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, PropsWithChildren, useState } from 'react';\nimport {\n configApiRef,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\nimport Snackbar from '@mui/material/Snackbar';\nimport CloseIcon from '@mui/icons-material/Close';\nimport IconButton from '@mui/material/IconButton';\nimport { QuickstartDrawerContext } from './QuickstartDrawerContext';\nimport { QuickstartDrawer } from './QuickstartDrawer';\nimport { QuickstartItemData } from '../types';\nimport { filterQuickstartItemsByRole } from '../utils';\nimport { useQuickstartRole } from '../hooks/useQuickstartRole';\n\n/**\n * Provider component for the Quickstart Drawer functionality\n * @public\n */\nexport const QuickstartDrawerProvider = ({ children }: PropsWithChildren) => {\n const [isDrawerOpen, setIsDrawerOpen] = useState<boolean>(false);\n const [showNotification, setShowNotification] = useState(false);\n const [hasShownNotification, setHasShownNotification] = useState(false);\n const [drawerWidth, setDrawerWidth] = useState<number>(500);\n const [userKey, setUserKey] = useState<string>('guest');\n const identityApi = useApi(identityApiRef);\n const configApi = useApi(configApiRef);\n\n // Determine role once at provider level to avoid re-fetching on drawer open/close\n const { isLoading: roleLoading, userRole } = useQuickstartRole();\n\n // Single useEffect - sets class on document.body\n useEffect(() => {\n if (isDrawerOpen) {\n document.body.classList.add('quickstart-drawer-open');\n document.body.style.setProperty(\n '--quickstart-drawer-width',\n `${drawerWidth}px`,\n );\n } else {\n document.body.classList.remove('quickstart-drawer-open');\n document.body.style.removeProperty('--quickstart-drawer-width');\n }\n\n return () => {\n document.body.classList.remove('quickstart-drawer-open');\n document.body.style.removeProperty('--quickstart-drawer-width');\n };\n }, [isDrawerOpen, drawerWidth]);\n\n // Resolve the current user's identity to scope localStorage keys per user\n useEffect(() => {\n let cancelled = false;\n (async () => {\n try {\n const identity = await identityApi.getBackstageIdentity();\n const ref = identity?.userEntityRef?.toLowerCase() || 'guest';\n if (!cancelled) setUserKey(ref);\n } catch (e) {\n if (!cancelled) setUserKey('guest');\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [identityApi]);\n\n // Initialize drawer state based on per-user keys and only when quickstarts exist\n useEffect(() => {\n if (!userKey) return;\n\n // Determine if there are any quickstart items configured globally\n const hasAnyQuickstarts = (() => {\n try {\n if (!configApi?.has('app.quickstart')) return false;\n const items = configApi.get('app.quickstart') as unknown;\n return Array.isArray(items) && items.length > 0;\n } catch {\n return false;\n }\n })();\n\n const openKey = `quickstart-open:${userKey}`;\n const visitedKey = `quickstart-visited:${userKey}`;\n const notificationKey = `quickstart-notification-shown:${userKey}`;\n\n // If no quickstarts are configured, ensure the drawer is closed and don't mark as visited\n if (!hasAnyQuickstarts) {\n setIsDrawerOpen(false);\n // Avoid persisting visited so future addition of items can auto-open\n localStorage.setItem(openKey, 'false');\n return;\n }\n\n // Check if user has any eligible quickstart items\n const quickstartItems: QuickstartItemData[] = configApi?.has(\n 'app.quickstart',\n )\n ? (configApi.get('app.quickstart') as QuickstartItemData[])\n : [];\n\n const eligibleItems =\n !roleLoading && userRole\n ? filterQuickstartItemsByRole(quickstartItems, userRole)\n : [];\n\n // If user has no eligible items, close the drawer and don't mark as visited\n if (!roleLoading && eligibleItems.length === 0) {\n setIsDrawerOpen(false);\n localStorage.setItem(openKey, 'false');\n return;\n }\n\n // Only proceed with drawer logic if user has eligible items\n const wasOpen = localStorage.getItem(openKey);\n const hasVisited = localStorage.getItem(visitedKey);\n const notificationShown = localStorage.getItem(notificationKey);\n\n if (!hasVisited) {\n setIsDrawerOpen(true);\n localStorage.setItem(visitedKey, 'true');\n localStorage.setItem(openKey, 'true');\n } else if (wasOpen === 'true') {\n setIsDrawerOpen(true);\n } else {\n setIsDrawerOpen(false);\n }\n\n setHasShownNotification(notificationShown === 'true');\n }, [userKey, configApi, roleLoading, userRole]);\n\n const openDrawer = () => {\n // Check if user has eligible items before opening\n const quickstartItems: QuickstartItemData[] = configApi?.has(\n 'app.quickstart',\n )\n ? (configApi.get('app.quickstart') as QuickstartItemData[])\n : [];\n\n const eligibleItems =\n !roleLoading && userRole\n ? filterQuickstartItemsByRole(quickstartItems, userRole)\n : [];\n\n // Only open if user has eligible items\n if (!roleLoading && eligibleItems.length > 0) {\n setIsDrawerOpen(true);\n const openKey = `quickstart-open:${userKey}`;\n localStorage.setItem(openKey, 'true');\n }\n };\n\n const closeDrawer = () => {\n setIsDrawerOpen(false);\n if (!hasShownNotification) {\n setShowNotification(true);\n setHasShownNotification(true);\n const notificationKey = `quickstart-notification-shown:${userKey}`;\n localStorage.setItem(notificationKey, 'true');\n }\n const openKey = `quickstart-open:${userKey}`;\n localStorage.setItem(openKey, 'false');\n };\n\n const toggleDrawer = () => {\n const next = !isDrawerOpen;\n setIsDrawerOpen(next);\n const openKey = `quickstart-open:${userKey}`;\n localStorage.setItem(openKey, next.toString());\n };\n\n const handleNotificationClose = () => setShowNotification(false);\n\n return (\n <QuickstartDrawerContext.Provider\n value={{\n isDrawerOpen,\n openDrawer,\n closeDrawer,\n toggleDrawer,\n setDrawerWidth,\n drawerWidth,\n userRole,\n roleLoading,\n }}\n >\n {children}\n <QuickstartDrawer />\n <Snackbar\n sx={{ top: '80px !important' }}\n open={showNotification}\n autoHideDuration={10000}\n onClose={handleNotificationClose}\n anchorOrigin={{ vertical: 'top', horizontal: 'right' }}\n message=\"Need help? Visit the Quick Start Guide by clicking on this (?) icon in the header!\"\n action={\n <IconButton\n size=\"small\"\n aria-label=\"close\"\n color=\"inherit\"\n onClick={handleNotificationClose}\n >\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n }\n />\n </QuickstartDrawerContext.Provider>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"QuickstartDrawerProvider.esm.js","sources":["../../src/components/QuickstartDrawerProvider.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, PropsWithChildren, useState } from 'react';\nimport {\n configApiRef,\n identityApiRef,\n useApi,\n} from '@backstage/core-plugin-api';\nimport Snackbar from '@mui/material/Snackbar';\nimport CloseIcon from '@mui/icons-material/Close';\nimport IconButton from '@mui/material/IconButton';\nimport { QuickstartDrawerContext } from './QuickstartDrawerContext';\nimport { QuickstartItemData } from '../types';\nimport { filterQuickstartItemsByRole } from '../utils';\nimport { useQuickstartRole } from '../hooks/useQuickstartRole';\n\n/**\n * Provider component for the Quickstart Drawer functionality\n * @public\n */\nexport const QuickstartDrawerProvider = ({ children }: PropsWithChildren) => {\n const [isDrawerOpen, setIsDrawerOpen] = useState<boolean>(false);\n const [showNotification, setShowNotification] = useState(false);\n const [hasShownNotification, setHasShownNotification] = useState(false);\n const [drawerWidth, setDrawerWidth] = useState<number>(500);\n const [userKey, setUserKey] = useState<string>('guest');\n const identityApi = useApi(identityApiRef);\n const configApi = useApi(configApiRef);\n\n // Determine role once at provider level to avoid re-fetching on drawer open/close\n const { isLoading: roleLoading, userRole } = useQuickstartRole();\n\n // Resolve the current user's identity to scope localStorage keys per user\n useEffect(() => {\n let cancelled = false;\n (async () => {\n try {\n const identity = await identityApi.getBackstageIdentity();\n const ref = identity?.userEntityRef?.toLowerCase() || 'guest';\n if (!cancelled) setUserKey(ref);\n } catch (e) {\n if (!cancelled) setUserKey('guest');\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [identityApi]);\n\n // Initialize drawer state based on per-user keys and only when quickstarts exist\n useEffect(() => {\n if (!userKey) return;\n\n // Determine if there are any quickstart items configured globally\n const hasAnyQuickstarts = (() => {\n try {\n if (!configApi?.has('app.quickstart')) return false;\n const items = configApi.get('app.quickstart') as unknown;\n return Array.isArray(items) && items.length > 0;\n } catch {\n return false;\n }\n })();\n\n const openKey = `quickstart-open:${userKey}`;\n const visitedKey = `quickstart-visited:${userKey}`;\n const notificationKey = `quickstart-notification-shown:${userKey}`;\n\n // If no quickstarts are configured, ensure the drawer is closed and don't mark as visited\n if (!hasAnyQuickstarts) {\n setIsDrawerOpen(false);\n // Avoid persisting visited so future addition of items can auto-open\n localStorage.setItem(openKey, 'false');\n return;\n }\n\n // Check if user has any eligible quickstart items\n const quickstartItems: QuickstartItemData[] = configApi?.has(\n 'app.quickstart',\n )\n ? (configApi.get('app.quickstart') as QuickstartItemData[])\n : [];\n\n const eligibleItems =\n !roleLoading && userRole\n ? filterQuickstartItemsByRole(quickstartItems, userRole)\n : [];\n\n // If user has no eligible items, close the drawer and don't mark as visited\n if (!roleLoading && eligibleItems.length === 0) {\n setIsDrawerOpen(false);\n localStorage.setItem(openKey, 'false');\n return;\n }\n\n // Only proceed with drawer logic if user has eligible items\n const wasOpen = localStorage.getItem(openKey);\n const hasVisited = localStorage.getItem(visitedKey);\n const notificationShown = localStorage.getItem(notificationKey);\n\n if (!hasVisited) {\n setIsDrawerOpen(true);\n localStorage.setItem(visitedKey, 'true');\n localStorage.setItem(openKey, 'true');\n } else if (wasOpen === 'true') {\n setIsDrawerOpen(true);\n } else {\n setIsDrawerOpen(false);\n }\n\n setHasShownNotification(notificationShown === 'true');\n }, [userKey, configApi, roleLoading, userRole]);\n\n const openDrawer = () => {\n // Check if user has eligible items before opening\n const quickstartItems: QuickstartItemData[] = configApi?.has(\n 'app.quickstart',\n )\n ? (configApi.get('app.quickstart') as QuickstartItemData[])\n : [];\n\n const eligibleItems =\n !roleLoading && userRole\n ? filterQuickstartItemsByRole(quickstartItems, userRole)\n : [];\n\n // Only open if user has eligible items\n if (!roleLoading && eligibleItems.length > 0) {\n setIsDrawerOpen(true);\n const openKey = `quickstart-open:${userKey}`;\n localStorage.setItem(openKey, 'true');\n }\n };\n\n const closeDrawer = () => {\n setIsDrawerOpen(false);\n if (!hasShownNotification) {\n setShowNotification(true);\n setHasShownNotification(true);\n const notificationKey = `quickstart-notification-shown:${userKey}`;\n localStorage.setItem(notificationKey, 'true');\n }\n const openKey = `quickstart-open:${userKey}`;\n localStorage.setItem(openKey, 'false');\n };\n\n const toggleDrawer = () => {\n const next = !isDrawerOpen;\n setIsDrawerOpen(next);\n const openKey = `quickstart-open:${userKey}`;\n localStorage.setItem(openKey, next.toString());\n };\n\n const handleNotificationClose = () => setShowNotification(false);\n\n return (\n <QuickstartDrawerContext.Provider\n value={{\n isDrawerOpen,\n openDrawer,\n closeDrawer,\n toggleDrawer,\n setDrawerWidth,\n drawerWidth,\n userRole,\n roleLoading,\n }}\n >\n {children}\n <Snackbar\n sx={{ top: '80px !important' }}\n open={showNotification}\n autoHideDuration={10000}\n onClose={handleNotificationClose}\n anchorOrigin={{ vertical: 'top', horizontal: 'right' }}\n message=\"Need help? Visit the Quick Start Guide by clicking on this (?) icon in the header!\"\n action={\n <IconButton\n size=\"small\"\n aria-label=\"close\"\n color=\"inherit\"\n onClick={handleNotificationClose}\n >\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n }\n />\n </QuickstartDrawerContext.Provider>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;AAkCO,MAAM,wBAA2B,GAAA,CAAC,EAAE,QAAA,EAAkC,KAAA;AAC3E,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAkB,KAAK,CAAA;AAC/D,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,SAAS,KAAK,CAAA;AAC9D,EAAA,MAAM,CAAC,oBAAA,EAAsB,uBAAuB,CAAA,GAAI,SAAS,KAAK,CAAA;AACtE,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAiB,GAAG,CAAA;AAC1D,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAiB,OAAO,CAAA;AACtD,EAAM,MAAA,WAAA,GAAc,OAAO,cAAc,CAAA;AACzC,EAAM,MAAA,SAAA,GAAY,OAAO,YAAY,CAAA;AAGrC,EAAA,MAAM,EAAE,SAAA,EAAW,WAAa,EAAA,QAAA,KAAa,iBAAkB,EAAA;AAG/D,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,SAAY,GAAA,KAAA;AAChB,IAAA,CAAC,YAAY;AACX,MAAI,IAAA;AACF,QAAM,MAAA,QAAA,GAAW,MAAM,WAAA,CAAY,oBAAqB,EAAA;AACxD,QAAA,MAAM,GAAM,GAAA,QAAA,EAAU,aAAe,EAAA,WAAA,EAAiB,IAAA,OAAA;AACtD,QAAI,IAAA,CAAC,SAAW,EAAA,UAAA,CAAW,GAAG,CAAA;AAAA,eACvB,CAAG,EAAA;AACV,QAAI,IAAA,CAAC,SAAW,EAAA,UAAA,CAAW,OAAO,CAAA;AAAA;AACpC,KACC,GAAA;AACH,IAAA,OAAO,MAAM;AACX,MAAY,SAAA,GAAA,IAAA;AAAA,KACd;AAAA,GACF,EAAG,CAAC,WAAW,CAAC,CAAA;AAGhB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,OAAS,EAAA;AAGd,IAAA,MAAM,qBAAqB,MAAM;AAC/B,MAAI,IAAA;AACF,QAAA,IAAI,CAAC,SAAA,EAAW,GAAI,CAAA,gBAAgB,GAAU,OAAA,KAAA;AAC9C,QAAM,MAAA,KAAA,GAAQ,SAAU,CAAA,GAAA,CAAI,gBAAgB,CAAA;AAC5C,QAAA,OAAO,KAAM,CAAA,OAAA,CAAQ,KAAK,CAAA,IAAK,MAAM,MAAS,GAAA,CAAA;AAAA,OACxC,CAAA,MAAA;AACN,QAAO,OAAA,KAAA;AAAA;AACT,KACC,GAAA;AAEH,IAAM,MAAA,OAAA,GAAU,mBAAmB,OAAO,CAAA,CAAA;AAC1C,IAAM,MAAA,UAAA,GAAa,sBAAsB,OAAO,CAAA,CAAA;AAChD,IAAM,MAAA,eAAA,GAAkB,iCAAiC,OAAO,CAAA,CAAA;AAGhE,IAAA,IAAI,CAAC,iBAAmB,EAAA;AACtB,MAAA,eAAA,CAAgB,KAAK,CAAA;AAErB,MAAa,YAAA,CAAA,OAAA,CAAQ,SAAS,OAAO,CAAA;AACrC,MAAA;AAAA;AAIF,IAAA,MAAM,kBAAwC,SAAW,EAAA,GAAA;AAAA,MACvD;AAAA,KAEG,GAAA,SAAA,CAAU,GAAI,CAAA,gBAAgB,IAC/B,EAAC;AAEL,IAAM,MAAA,aAAA,GACJ,CAAC,WAAe,IAAA,QAAA,GACZ,4BAA4B,eAAiB,EAAA,QAAQ,IACrD,EAAC;AAGP,IAAA,IAAI,CAAC,WAAA,IAAe,aAAc,CAAA,MAAA,KAAW,CAAG,EAAA;AAC9C,MAAA,eAAA,CAAgB,KAAK,CAAA;AACrB,MAAa,YAAA,CAAA,OAAA,CAAQ,SAAS,OAAO,CAAA;AACrC,MAAA;AAAA;AAIF,IAAM,MAAA,OAAA,GAAU,YAAa,CAAA,OAAA,CAAQ,OAAO,CAAA;AAC5C,IAAM,MAAA,UAAA,GAAa,YAAa,CAAA,OAAA,CAAQ,UAAU,CAAA;AAClD,IAAM,MAAA,iBAAA,GAAoB,YAAa,CAAA,OAAA,CAAQ,eAAe,CAAA;AAE9D,IAAA,IAAI,CAAC,UAAY,EAAA;AACf,MAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,MAAa,YAAA,CAAA,OAAA,CAAQ,YAAY,MAAM,CAAA;AACvC,MAAa,YAAA,CAAA,OAAA,CAAQ,SAAS,MAAM,CAAA;AAAA,KACtC,MAAA,IAAW,YAAY,MAAQ,EAAA;AAC7B,MAAA,eAAA,CAAgB,IAAI,CAAA;AAAA,KACf,MAAA;AACL,MAAA,eAAA,CAAgB,KAAK,CAAA;AAAA;AAGvB,IAAA,uBAAA,CAAwB,sBAAsB,MAAM,CAAA;AAAA,KACnD,CAAC,OAAA,EAAS,SAAW,EAAA,WAAA,EAAa,QAAQ,CAAC,CAAA;AAE9C,EAAA,MAAM,aAAa,MAAM;AAEvB,IAAA,MAAM,kBAAwC,SAAW,EAAA,GAAA;AAAA,MACvD;AAAA,KAEG,GAAA,SAAA,CAAU,GAAI,CAAA,gBAAgB,IAC/B,EAAC;AAEL,IAAM,MAAA,aAAA,GACJ,CAAC,WAAe,IAAA,QAAA,GACZ,4BAA4B,eAAiB,EAAA,QAAQ,IACrD,EAAC;AAGP,IAAA,IAAI,CAAC,WAAA,IAAe,aAAc,CAAA,MAAA,GAAS,CAAG,EAAA;AAC5C,MAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,MAAM,MAAA,OAAA,GAAU,mBAAmB,OAAO,CAAA,CAAA;AAC1C,MAAa,YAAA,CAAA,OAAA,CAAQ,SAAS,MAAM,CAAA;AAAA;AACtC,GACF;AAEA,EAAA,MAAM,cAAc,MAAM;AACxB,IAAA,eAAA,CAAgB,KAAK,CAAA;AACrB,IAAA,IAAI,CAAC,oBAAsB,EAAA;AACzB,MAAA,mBAAA,CAAoB,IAAI,CAAA;AACxB,MAAA,uBAAA,CAAwB,IAAI,CAAA;AAC5B,MAAM,MAAA,eAAA,GAAkB,iCAAiC,OAAO,CAAA,CAAA;AAChE,MAAa,YAAA,CAAA,OAAA,CAAQ,iBAAiB,MAAM,CAAA;AAAA;AAE9C,IAAM,MAAA,OAAA,GAAU,mBAAmB,OAAO,CAAA,CAAA;AAC1C,IAAa,YAAA,CAAA,OAAA,CAAQ,SAAS,OAAO,CAAA;AAAA,GACvC;AAEA,EAAA,MAAM,eAAe,MAAM;AACzB,IAAA,MAAM,OAAO,CAAC,YAAA;AACd,IAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,IAAM,MAAA,OAAA,GAAU,mBAAmB,OAAO,CAAA,CAAA;AAC1C,IAAA,YAAA,CAAa,OAAQ,CAAA,OAAA,EAAS,IAAK,CAAA,QAAA,EAAU,CAAA;AAAA,GAC/C;AAEA,EAAM,MAAA,uBAAA,GAA0B,MAAM,mBAAA,CAAoB,KAAK,CAAA;AAE/D,EACE,uBAAA,IAAA;AAAA,IAAC,uBAAwB,CAAA,QAAA;AAAA,IAAxB;AAAA,MACC,KAAO,EAAA;AAAA,QACL,YAAA;AAAA,QACA,UAAA;AAAA,QACA,WAAA;AAAA,QACA,YAAA;AAAA,QACA,cAAA;AAAA,QACA,WAAA;AAAA,QACA,QAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,QAAA;AAAA,wBACD,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,EAAA,EAAI,EAAE,GAAA,EAAK,iBAAkB,EAAA;AAAA,YAC7B,IAAM,EAAA,gBAAA;AAAA,YACN,gBAAkB,EAAA,GAAA;AAAA,YAClB,OAAS,EAAA,uBAAA;AAAA,YACT,YAAc,EAAA,EAAE,QAAU,EAAA,KAAA,EAAO,YAAY,OAAQ,EAAA;AAAA,YACrD,OAAQ,EAAA,oFAAA;AAAA,YACR,MACE,kBAAA,GAAA;AAAA,cAAC,UAAA;AAAA,cAAA;AAAA,gBACC,IAAK,EAAA,OAAA;AAAA,gBACL,YAAW,EAAA,OAAA;AAAA,gBACX,KAAM,EAAA,SAAA;AAAA,gBACN,OAAS,EAAA,uBAAA;AAAA,gBAET,QAAA,kBAAA,GAAA,CAAC,SAAU,EAAA,EAAA,QAAA,EAAS,OAAQ,EAAA;AAAA;AAAA;AAC9B;AAAA;AAEJ;AAAA;AAAA,GACF;AAEJ;;;;"}
@@ -0,0 +1,32 @@
1
+ import { useRef, useCallback, useEffect } from 'react';
2
+ import { useQuickstartDrawerContext } from '../hooks/useQuickstartDrawerContext.esm.js';
3
+
4
+ const QuickstartDrawerStateExposer = ({
5
+ onStateChange
6
+ }) => {
7
+ const { isDrawerOpen, drawerWidth, setDrawerWidth, closeDrawer } = useQuickstartDrawerContext();
8
+ const closeDrawerRef = useRef(closeDrawer);
9
+ closeDrawerRef.current = closeDrawer;
10
+ const closeQuickstart = useCallback(() => {
11
+ closeDrawerRef.current();
12
+ }, []);
13
+ useEffect(() => {
14
+ onStateChange({
15
+ id: "quickstart",
16
+ isDrawerOpen,
17
+ drawerWidth,
18
+ setDrawerWidth,
19
+ closeDrawer: closeQuickstart
20
+ });
21
+ }, [
22
+ isDrawerOpen,
23
+ drawerWidth,
24
+ setDrawerWidth,
25
+ onStateChange,
26
+ closeQuickstart
27
+ ]);
28
+ return null;
29
+ };
30
+
31
+ export { QuickstartDrawerStateExposer };
32
+ //# sourceMappingURL=QuickstartDrawerStateExposer.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuickstartDrawerStateExposer.esm.js","sources":["../../src/components/QuickstartDrawerStateExposer.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 { useCallback, useEffect, useRef } from 'react';\nimport { useQuickstartDrawerContext } from '../hooks/useQuickstartDrawerContext';\n\n/**\n * Partial drawer state exposed to the ApplicationDrawer\n *\n * @public\n */\nexport type DrawerPartialState = {\n id: string;\n isDrawerOpen: boolean;\n drawerWidth: number;\n setDrawerWidth: (width: number) => void;\n closeDrawer: () => void;\n};\n\n/**\n * Props for drawer state exposer components\n *\n * @public\n */\nexport type DrawerStateExposerProps = {\n /**\n * Callback called whenever the drawer state changes\n */\n onStateChange: (state: DrawerPartialState) => void;\n};\n\n/**\n * This exposes Quickstart Drawer's partial context to the ApplicationDrawer\n *\n * It reads the QuickstartDrawerContext and calls the onStateChange callback with the\n * partial state (id, isDrawerOpen, drawerWidth, setDrawerWidth).\n *\n * @public\n */\nexport const QuickstartDrawerStateExposer = ({\n onStateChange,\n}: DrawerStateExposerProps) => {\n const { isDrawerOpen, drawerWidth, setDrawerWidth, closeDrawer } =\n useQuickstartDrawerContext();\n\n const closeDrawerRef = useRef(closeDrawer);\n closeDrawerRef.current = closeDrawer;\n\n const closeQuickstart = useCallback(() => {\n closeDrawerRef.current();\n }, []);\n\n useEffect(() => {\n onStateChange({\n id: 'quickstart',\n isDrawerOpen,\n drawerWidth,\n setDrawerWidth,\n closeDrawer: closeQuickstart,\n });\n }, [\n isDrawerOpen,\n drawerWidth,\n setDrawerWidth,\n onStateChange,\n closeQuickstart,\n ]);\n\n return null;\n};\n"],"names":[],"mappings":";;;AAoDO,MAAM,+BAA+B,CAAC;AAAA,EAC3C;AACF,CAA+B,KAAA;AAC7B,EAAA,MAAM,EAAE,YAAc,EAAA,WAAA,EAAa,cAAgB,EAAA,WAAA,KACjD,0BAA2B,EAAA;AAE7B,EAAM,MAAA,cAAA,GAAiB,OAAO,WAAW,CAAA;AACzC,EAAA,cAAA,CAAe,OAAU,GAAA,WAAA;AAEzB,EAAM,MAAA,eAAA,GAAkB,YAAY,MAAM;AACxC,IAAA,cAAA,CAAe,OAAQ,EAAA;AAAA,GACzB,EAAG,EAAE,CAAA;AAEL,EAAA,SAAA,CAAU,MAAM;AACd,IAAc,aAAA,CAAA;AAAA,MACZ,EAAI,EAAA,YAAA;AAAA,MACJ,YAAA;AAAA,MACA,WAAA;AAAA,MACA,cAAA;AAAA,MACA,WAAa,EAAA;AAAA,KACd,CAAA;AAAA,GACA,EAAA;AAAA,IACD,YAAA;AAAA,IACA,WAAA;AAAA,IACA,cAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAO,OAAA,IAAA;AACT;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,43 @@
1
1
  /// <reference types="react" />
2
- import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
3
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
4
4
  import { CSSProperties, PropsWithChildren } from 'react';
5
5
  export { quickstartTranslationRef, quickstartTranslations } from './alpha.js';
6
6
  import '@backstage/core-plugin-api/alpha';
7
7
 
8
+ /**
9
+ * Partial drawer state exposed to the ApplicationDrawer
10
+ *
11
+ * @public
12
+ */
13
+ type DrawerPartialState = {
14
+ id: string;
15
+ isDrawerOpen: boolean;
16
+ drawerWidth: number;
17
+ setDrawerWidth: (width: number) => void;
18
+ closeDrawer: () => void;
19
+ };
20
+ /**
21
+ * Props for drawer state exposer components
22
+ *
23
+ * @public
24
+ */
25
+ type DrawerStateExposerProps = {
26
+ /**
27
+ * Callback called whenever the drawer state changes
28
+ */
29
+ onStateChange: (state: DrawerPartialState) => void;
30
+ };
31
+ /**
32
+ * This exposes Quickstart Drawer's partial context to the ApplicationDrawer
33
+ *
34
+ * It reads the QuickstartDrawerContext and calls the onStateChange callback with the
35
+ * partial state (id, isDrawerOpen, drawerWidth, setDrawerWidth).
36
+ *
37
+ * @public
38
+ */
39
+ declare const QuickstartDrawerStateExposer: ({ onStateChange, }: DrawerStateExposerProps) => null;
40
+
8
41
  /**
9
42
  * Props for the QuickstartButton component
10
43
  * @public
@@ -36,6 +69,12 @@ declare const QuickstartButton: ({ title, style, onClick, }: QuickstartButtonPro
36
69
  * @public
37
70
  */
38
71
  declare const quickstartPlugin: _backstage_core_plugin_api.BackstagePlugin<{}, {}, {}>;
72
+ /**
73
+ * Quickstart Drawer Content component extension
74
+ *
75
+ * @public
76
+ */
77
+ declare const QuickstartDrawerContent: () => react_jsx_runtime.JSX.Element | null;
39
78
 
40
79
  /**
41
80
  * Call-to-action data for quickstart items
@@ -139,5 +178,5 @@ declare const QuickstartDrawerProvider: ({ children }: PropsWithChildren) => rea
139
178
  */
140
179
  declare const filterQuickstartItemsByRole: (items: QuickstartItemData[], userRole: string) => QuickstartItemData[];
141
180
 
142
- export { QuickstartButton, QuickstartDrawerProvider, filterQuickstartItemsByRole, quickstartPlugin, useQuickstartDrawerContext };
143
- export type { QuickstartButtonProps, QuickstartDrawerContextType, QuickstartItemCtaData, QuickstartItemData, UserRole };
181
+ export { QuickstartButton, QuickstartDrawerContent, QuickstartDrawerProvider, QuickstartDrawerStateExposer, filterQuickstartItemsByRole, quickstartPlugin, useQuickstartDrawerContext };
182
+ export type { DrawerPartialState, DrawerStateExposerProps, QuickstartButtonProps, QuickstartDrawerContextType, QuickstartItemCtaData, QuickstartItemData, UserRole };
package/dist/index.esm.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { unstable_ClassNameGenerator } from '@mui/material/className';
2
- export { quickstartPlugin } from './plugin.esm.js';
2
+ export { QuickstartDrawerContent, quickstartPlugin } from './plugin.esm.js';
3
3
  export { useQuickstartDrawerContext } from './hooks/useQuickstartDrawerContext.esm.js';
4
+ export { QuickstartDrawerStateExposer } from './components/QuickstartDrawerStateExposer.esm.js';
4
5
  export { QuickstartButton } from './components/QuickstartButton/QuickstartButton.esm.js';
5
6
  export { QuickstartDrawerProvider } from './components/QuickstartDrawerProvider.esm.js';
6
7
  export { quickstartTranslations } from './translations/index.esm.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/index.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { unstable_ClassNameGenerator as ClassNameGenerator } from '@mui/material/className';\n\nClassNameGenerator.configure(componentName => {\n return componentName.startsWith('v5-')\n ? componentName\n : `v5-${componentName}`;\n});\n\nexport * from './plugin';\n\nexport { useQuickstartDrawerContext } from './hooks/useQuickstartDrawerContext';\nexport type { QuickstartDrawerContextType } from './components/QuickstartDrawerContext';\n/**\n * @public\n */\nexport type {\n UserRole,\n QuickstartItemData,\n QuickstartItemCtaData,\n} from './types';\nexport { QuickstartButton } from './components/QuickstartButton/QuickstartButton';\nexport type { QuickstartButtonProps } from './components/QuickstartButton/QuickstartButton';\n/**\n * @public\n */\nexport { QuickstartDrawerProvider } from './components/QuickstartDrawerProvider';\n\nexport {\n quickstartTranslations,\n quickstartTranslationRef,\n} from './translations';\n\nexport { filterQuickstartItemsByRole } from './utils';\n"],"names":["ClassNameGenerator"],"mappings":";;;;;;;;;AAkBAA,2BAAA,CAAmB,UAAU,CAAiB,aAAA,KAAA;AAC5C,EAAA,OAAO,cAAc,UAAW,CAAA,KAAK,CACjC,GAAA,aAAA,GACA,MAAM,aAAa,CAAA,CAAA;AACzB,CAAC,CAAA"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/index.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { unstable_ClassNameGenerator as ClassNameGenerator } from '@mui/material/className';\n\nClassNameGenerator.configure(componentName => {\n return componentName.startsWith('v5-')\n ? componentName\n : `v5-${componentName}`;\n});\n\nexport * from './plugin';\n\nexport { useQuickstartDrawerContext } from './hooks/useQuickstartDrawerContext';\nexport type { QuickstartDrawerContextType } from './components/QuickstartDrawerContext';\nexport { QuickstartDrawerStateExposer } from './components/QuickstartDrawerStateExposer';\nexport type {\n DrawerStateExposerProps,\n DrawerPartialState,\n} from './components/QuickstartDrawerStateExposer';\n/**\n * @public\n */\nexport type {\n UserRole,\n QuickstartItemData,\n QuickstartItemCtaData,\n} from './types';\nexport { QuickstartButton } from './components/QuickstartButton/QuickstartButton';\nexport type { QuickstartButtonProps } from './components/QuickstartButton/QuickstartButton';\n/**\n * @public\n */\nexport { QuickstartDrawerProvider } from './components/QuickstartDrawerProvider';\n\nexport {\n quickstartTranslations,\n quickstartTranslationRef,\n} from './translations';\n\nexport { filterQuickstartItemsByRole } from './utils';\n"],"names":["ClassNameGenerator"],"mappings":";;;;;;;;;;AAkBAA,2BAAA,CAAmB,UAAU,CAAiB,aAAA,KAAA;AAC5C,EAAA,OAAO,cAAc,UAAW,CAAA,KAAK,CACjC,GAAA,aAAA,GACA,MAAM,aAAa,CAAA,CAAA;AACzB,CAAC,CAAA"}
@@ -19,6 +19,16 @@ quickstartPlugin.provide(
19
19
  }
20
20
  })
21
21
  );
22
+ const QuickstartDrawerContent = quickstartPlugin.provide(
23
+ createComponentExtension({
24
+ name: "QuickstartDrawerContent",
25
+ component: {
26
+ lazy: () => import('./components/QuickstartDrawerContent.esm.js').then(
27
+ (m) => m.QuickstartDrawerContent
28
+ )
29
+ }
30
+ })
31
+ );
22
32
  quickstartPlugin.provide(
23
33
  createComponentExtension({
24
34
  name: "QuickstartButton",
@@ -29,6 +39,16 @@ quickstartPlugin.provide(
29
39
  }
30
40
  })
31
41
  );
42
+ quickstartPlugin.provide(
43
+ createComponentExtension({
44
+ name: "QuickstartDrawerStateExposer",
45
+ component: {
46
+ lazy: () => import('./components/QuickstartDrawerStateExposer.esm.js').then(
47
+ (m) => m.QuickstartDrawerStateExposer
48
+ )
49
+ }
50
+ })
51
+ );
32
52
 
33
- export { quickstartPlugin };
53
+ export { QuickstartDrawerContent, quickstartPlugin };
34
54
  //# sourceMappingURL=plugin.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createComponentExtension,\n createPlugin,\n} from '@backstage/core-plugin-api';\nimport { PropsWithChildren } from 'react';\nimport { QuickstartButtonProps } from './components/QuickstartButton/QuickstartButton';\nimport { quickstartTranslationRef } from './translations';\n\nexport type { QuickstartButtonProps } from './components/QuickstartButton/QuickstartButton';\n\n/**\n * Quick start plugin\n *\n * @public\n */\nexport const quickstartPlugin = createPlugin({\n id: 'quickstart',\n __experimentalTranslations: {\n availableLanguages: ['en', 'de', 'es', 'fr', 'it', 'ja'],\n resources: [quickstartTranslationRef],\n },\n} as any);\n\n/**\n * Quick start drawer provider\n *\n * @public\n */\nexport const QuickstartDrawerProvider: React.ComponentType<PropsWithChildren> =\n quickstartPlugin.provide(\n createComponentExtension({\n name: 'QuickstartDrawerProvider',\n component: {\n lazy: () =>\n import('./components/QuickstartDrawerProvider').then(\n m => m.QuickstartDrawerProvider,\n ),\n },\n }),\n );\n\n/**\n * Quick start button for global header help dropdown\n *\n * @public\n */\nexport const QuickstartButton: React.ComponentType<QuickstartButtonProps> =\n quickstartPlugin.provide(\n createComponentExtension({\n name: 'QuickstartButton',\n component: {\n lazy: () =>\n import('./components/QuickstartButton/QuickstartButton').then(\n m => m.QuickstartButton,\n ),\n },\n }),\n );\n"],"names":[],"mappings":";;;;AA+BO,MAAM,mBAAmB,YAAa,CAAA;AAAA,EAC3C,EAAI,EAAA,YAAA;AAAA,EACJ,0BAA4B,EAAA;AAAA,IAC1B,oBAAoB,CAAC,IAAA,EAAM,MAAM,IAAM,EAAA,IAAA,EAAM,MAAM,IAAI,CAAA;AAAA,IACvD,SAAA,EAAW,CAAC,wBAAwB;AAAA;AAExC,CAAQ;AAQN,gBAAiB,CAAA,OAAA;AAAA,EACf,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,0BAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAM,EAAA,MACJ,OAAO,8CAAuC,CAAE,CAAA,IAAA;AAAA,QAC9C,OAAK,CAAE,CAAA;AAAA;AACT;AACJ,GACD;AACH;AAQA,gBAAiB,CAAA,OAAA;AAAA,EACf,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,kBAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAM,EAAA,MACJ,OAAO,uDAAgD,CAAE,CAAA,IAAA;AAAA,QACvD,OAAK,CAAE,CAAA;AAAA;AACT;AACJ,GACD;AACH;;;;"}
1
+ {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createComponentExtension,\n createPlugin,\n} from '@backstage/core-plugin-api';\nimport { PropsWithChildren } from 'react';\nimport { QuickstartButtonProps } from './components/QuickstartButton/QuickstartButton';\nimport { quickstartTranslationRef } from './translations';\n\nexport type { QuickstartButtonProps } from './components/QuickstartButton/QuickstartButton';\n\n/**\n * Quick start plugin\n *\n * @public\n */\nexport const quickstartPlugin = createPlugin({\n id: 'quickstart',\n __experimentalTranslations: {\n availableLanguages: ['en', 'de', 'es', 'fr', 'it', 'ja'],\n resources: [quickstartTranslationRef],\n },\n} as any);\n\n/**\n * Quick start drawer provider\n *\n * @public\n */\nexport const QuickstartDrawerProvider: React.ComponentType<PropsWithChildren> =\n quickstartPlugin.provide(\n createComponentExtension({\n name: 'QuickstartDrawerProvider',\n component: {\n lazy: () =>\n import('./components/QuickstartDrawerProvider').then(\n m => m.QuickstartDrawerProvider,\n ),\n },\n }),\n );\n\n/**\n * Quickstart Drawer Content component extension\n *\n * @public\n */\nexport const QuickstartDrawerContent = quickstartPlugin.provide(\n createComponentExtension({\n name: 'QuickstartDrawerContent',\n component: {\n lazy: () =>\n import('./components/QuickstartDrawerContent').then(\n m => m.QuickstartDrawerContent,\n ),\n },\n }),\n);\n\n/**\n * Quick start button for global header help dropdown\n *\n * @public\n */\nexport const QuickstartButton: React.ComponentType<QuickstartButtonProps> =\n quickstartPlugin.provide(\n createComponentExtension({\n name: 'QuickstartButton',\n component: {\n lazy: () =>\n import('./components/QuickstartButton/QuickstartButton').then(\n m => m.QuickstartButton,\n ),\n },\n }),\n );\n\n/**\n * Quickstart Drawer State Exposer exposes its drawer state\n *\n * @public\n */\nexport const QuickstartDrawerStateExposer = quickstartPlugin.provide(\n createComponentExtension({\n name: 'QuickstartDrawerStateExposer',\n component: {\n lazy: () =>\n import('./components/QuickstartDrawerStateExposer').then(\n m => m.QuickstartDrawerStateExposer,\n ),\n },\n }),\n);\n"],"names":[],"mappings":";;;;AA+BO,MAAM,mBAAmB,YAAa,CAAA;AAAA,EAC3C,EAAI,EAAA,YAAA;AAAA,EACJ,0BAA4B,EAAA;AAAA,IAC1B,oBAAoB,CAAC,IAAA,EAAM,MAAM,IAAM,EAAA,IAAA,EAAM,MAAM,IAAI,CAAA;AAAA,IACvD,SAAA,EAAW,CAAC,wBAAwB;AAAA;AAExC,CAAQ;AAQN,gBAAiB,CAAA,OAAA;AAAA,EACf,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,0BAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAM,EAAA,MACJ,OAAO,8CAAuC,CAAE,CAAA,IAAA;AAAA,QAC9C,OAAK,CAAE,CAAA;AAAA;AACT;AACJ,GACD;AACH;AAOK,MAAM,0BAA0B,gBAAiB,CAAA,OAAA;AAAA,EACtD,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,yBAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAM,EAAA,MACJ,OAAO,6CAAsC,CAAE,CAAA,IAAA;AAAA,QAC7C,OAAK,CAAE,CAAA;AAAA;AACT;AACJ,GACD;AACH;AAQE,gBAAiB,CAAA,OAAA;AAAA,EACf,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,kBAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAM,EAAA,MACJ,OAAO,uDAAgD,CAAE,CAAA,IAAA;AAAA,QACvD,OAAK,CAAE,CAAA;AAAA;AACT;AACJ,GACD;AACH;AAO0C,gBAAiB,CAAA,OAAA;AAAA,EAC3D,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,8BAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAM,EAAA,MACJ,OAAO,kDAA2C,CAAE,CAAA,IAAA;AAAA,QAClD,OAAK,CAAE,CAAA;AAAA;AACT;AACJ,GACD;AACH;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@red-hat-developer-hub/backstage-plugin-quickstart",
3
- "version": "1.8.1",
3
+ "version": "1.8.2",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./dist/index.esm.js",
6
6
  "types": "./dist/index.d.ts",
@@ -1,62 +0,0 @@
1
- import { jsx } from 'react/jsx-runtime';
2
- import Drawer from '@mui/material/Drawer';
3
- import { useApiHolder, configApiRef } from '@backstage/core-plugin-api';
4
- import { Quickstart } from './Quickstart.esm.js';
5
- import { useQuickstartDrawerContext } from '../hooks/useQuickstartDrawerContext.esm.js';
6
- import { filterQuickstartItemsByRole } from '../utils/filterQuickstartItems.esm.js';
7
- import { useMemo } from 'react';
8
-
9
- const QuickstartDrawer = () => {
10
- const { isDrawerOpen, closeDrawer, drawerWidth, userRole, roleLoading } = useQuickstartDrawerContext();
11
- const apiHolder = useApiHolder();
12
- const config = apiHolder.get(configApiRef);
13
- const quickstartItems = useMemo(() => {
14
- return config?.has("app.quickstart") ? config.get("app.quickstart") : [];
15
- }, [config]);
16
- const eligibleItems = useMemo(() => {
17
- return !roleLoading && userRole ? filterQuickstartItemsByRole(quickstartItems, userRole) : [];
18
- }, [roleLoading, userRole, quickstartItems]);
19
- const filteredItems = useMemo(() => {
20
- return isDrawerOpen ? eligibleItems : [];
21
- }, [isDrawerOpen, eligibleItems]);
22
- if (quickstartItems.length === 0) {
23
- return null;
24
- }
25
- if (!roleLoading && eligibleItems.length === 0) {
26
- return null;
27
- }
28
- return /* @__PURE__ */ jsx(
29
- Drawer,
30
- {
31
- sx: {
32
- "& .v5-MuiDrawer-paper": {
33
- width: drawerWidth,
34
- boxSizing: "border-box",
35
- backgroundColor: (theme) => `${theme.palette?.rhdh?.general.sidebarBackgroundColor}`,
36
- justifyContent: "space-between"
37
- },
38
- // Only apply header offset when global header exists
39
- "body:has(#global-header) &": {
40
- "& .v5-MuiDrawer-paper": {
41
- top: "64px !important",
42
- height: "calc(100vh - 64px) !important"
43
- }
44
- }
45
- },
46
- variant: "persistent",
47
- anchor: "right",
48
- open: isDrawerOpen,
49
- children: /* @__PURE__ */ jsx(
50
- Quickstart,
51
- {
52
- quickstartItems: filteredItems,
53
- handleDrawerClose: closeDrawer,
54
- isLoading: roleLoading
55
- }
56
- )
57
- }
58
- );
59
- };
60
-
61
- export { QuickstartDrawer };
62
- //# sourceMappingURL=QuickstartDrawer.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"QuickstartDrawer.esm.js","sources":["../../src/components/QuickstartDrawer.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 Drawer from '@mui/material/Drawer';\nimport { ThemeConfig } from '@red-hat-developer-hub/backstage-plugin-theme';\nimport { configApiRef, useApiHolder } from '@backstage/core-plugin-api';\nimport { Quickstart } from './Quickstart';\nimport { useQuickstartDrawerContext } from '../hooks/useQuickstartDrawerContext';\nimport { QuickstartItemData } from '../types';\nimport { filterQuickstartItemsByRole } from '../utils';\n// Role is now provided through context to avoid re-fetching on drawer open/close\nimport { useMemo } from 'react';\n\nexport const QuickstartDrawer = () => {\n const { isDrawerOpen, closeDrawer, drawerWidth, userRole, roleLoading } =\n useQuickstartDrawerContext();\n\n const apiHolder = useApiHolder();\n const config = apiHolder.get(configApiRef);\n const quickstartItems: QuickstartItemData[] = useMemo(() => {\n return config?.has('app.quickstart')\n ? (config.get('app.quickstart') as QuickstartItemData[])\n : [];\n }, [config]);\n\n // Items available to the user based on role from context\n const eligibleItems = useMemo(() => {\n return !roleLoading && userRole\n ? filterQuickstartItemsByRole(quickstartItems, userRole)\n : [];\n }, [roleLoading, userRole, quickstartItems]);\n\n // Only expose items to the body when drawer is open to avoid re-renders during close\n const filteredItems = useMemo(() => {\n return isDrawerOpen ? eligibleItems : [];\n }, [isDrawerOpen, eligibleItems]);\n\n // No auto-open logic here; the provider initializes per user (visited/open)\n\n // If no quickstart items are configured at all, don't render the drawer to avoid reserving space\n if (quickstartItems.length === 0) {\n return null;\n }\n\n // If there are no items for the user, hide the drawer entirely\n if (!roleLoading && eligibleItems.length === 0) {\n return null;\n }\n\n // No role-fetching or filtering here when the drawer is closed\n\n return (\n <Drawer\n sx={{\n '& .v5-MuiDrawer-paper': {\n width: drawerWidth,\n boxSizing: 'border-box',\n backgroundColor: theme =>\n `${\n (theme as ThemeConfig).palette?.rhdh?.general\n .sidebarBackgroundColor\n }`,\n justifyContent: 'space-between',\n },\n // Only apply header offset when global header exists\n 'body:has(#global-header) &': {\n '& .v5-MuiDrawer-paper': {\n top: '64px !important',\n height: 'calc(100vh - 64px) !important',\n },\n },\n }}\n variant=\"persistent\"\n anchor=\"right\"\n open={isDrawerOpen}\n >\n <Quickstart\n quickstartItems={filteredItems}\n handleDrawerClose={closeDrawer}\n isLoading={roleLoading}\n />\n </Drawer>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AA0BO,MAAM,mBAAmB,MAAM;AACpC,EAAA,MAAM,EAAE,YAAc,EAAA,WAAA,EAAa,aAAa,QAAU,EAAA,WAAA,KACxD,0BAA2B,EAAA;AAE7B,EAAA,MAAM,YAAY,YAAa,EAAA;AAC/B,EAAM,MAAA,MAAA,GAAS,SAAU,CAAA,GAAA,CAAI,YAAY,CAAA;AACzC,EAAM,MAAA,eAAA,GAAwC,QAAQ,MAAM;AAC1D,IAAO,OAAA,MAAA,EAAQ,IAAI,gBAAgB,CAAA,GAC9B,OAAO,GAAI,CAAA,gBAAgB,IAC5B,EAAC;AAAA,GACP,EAAG,CAAC,MAAM,CAAC,CAAA;AAGX,EAAM,MAAA,aAAA,GAAgB,QAAQ,MAAM;AAClC,IAAA,OAAO,CAAC,WAAe,IAAA,QAAA,GACnB,4BAA4B,eAAiB,EAAA,QAAQ,IACrD,EAAC;AAAA,GACJ,EAAA,CAAC,WAAa,EAAA,QAAA,EAAU,eAAe,CAAC,CAAA;AAG3C,EAAM,MAAA,aAAA,GAAgB,QAAQ,MAAM;AAClC,IAAO,OAAA,YAAA,GAAe,gBAAgB,EAAC;AAAA,GACtC,EAAA,CAAC,YAAc,EAAA,aAAa,CAAC,CAAA;AAKhC,EAAI,IAAA,eAAA,CAAgB,WAAW,CAAG,EAAA;AAChC,IAAO,OAAA,IAAA;AAAA;AAIT,EAAA,IAAI,CAAC,WAAA,IAAe,aAAc,CAAA,MAAA,KAAW,CAAG,EAAA;AAC9C,IAAO,OAAA,IAAA;AAAA;AAKT,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,EAAI,EAAA;AAAA,QACF,uBAAyB,EAAA;AAAA,UACvB,KAAO,EAAA,WAAA;AAAA,UACP,SAAW,EAAA,YAAA;AAAA,UACX,iBAAiB,CACf,KAAA,KAAA,CAAA,EACG,MAAsB,OAAS,EAAA,IAAA,EAAM,QACnC,sBACL,CAAA,CAAA;AAAA,UACF,cAAgB,EAAA;AAAA,SAClB;AAAA;AAAA,QAEA,4BAA8B,EAAA;AAAA,UAC5B,uBAAyB,EAAA;AAAA,YACvB,GAAK,EAAA,iBAAA;AAAA,YACL,MAAQ,EAAA;AAAA;AACV;AACF,OACF;AAAA,MACA,OAAQ,EAAA,YAAA;AAAA,MACR,MAAO,EAAA,OAAA;AAAA,MACP,IAAM,EAAA,YAAA;AAAA,MAEN,QAAA,kBAAA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,eAAiB,EAAA,aAAA;AAAA,UACjB,iBAAmB,EAAA,WAAA;AAAA,UACnB,SAAW,EAAA;AAAA;AAAA;AACb;AAAA,GACF;AAEJ;;;;"}