From f4dab370f6409b1ad08801820c5d1b2d122e7d3d Mon Sep 17 00:00:00 2001 From: debsmita1 Date: Wed, 22 Jan 2025 12:34:14 +0530 Subject: [PATCH] feat(fab): created dynamic fab to be integrated in the RHDH app --- .../.changeset/funny-jars-itch.md | 5 + .../global-floating-action-button/README.md | 56 ++++++- .../app-config.dynamic.yaml | 6 + .../dev/ExampleComponent/ExampleComponent.tsx | 63 +------- .../ExampleFetchComponent.tsx | 1 + .../dev/index.tsx | 153 +++++++++++++++++- .../package.json | 2 + .../report.api.md | 15 ++ .../DynamicGlobalFloatingActionButton.tsx | 36 +++++ .../src/components/FAB.tsx | 21 ++- .../src/components/FABWithSubmenu.tsx | 5 +- .../src/components/FloatingButton.tsx | 9 +- .../src/components/index.ts | 1 + .../src/hooks/useFabMountPoints.ts | 39 +++++ .../src/plugin.test.ts | 12 +- .../src/plugin.ts | 27 ++++ .../src/types.ts | 9 ++ .../global-floating-action-button/yarn.lock | 75 ++++++++- 18 files changed, 464 insertions(+), 71 deletions(-) create mode 100644 workspaces/global-floating-action-button/.changeset/funny-jars-itch.md create mode 100644 workspaces/global-floating-action-button/plugins/global-floating-action-button/app-config.dynamic.yaml create mode 100644 workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/DynamicGlobalFloatingActionButton.tsx create mode 100644 workspaces/global-floating-action-button/plugins/global-floating-action-button/src/hooks/useFabMountPoints.ts diff --git a/workspaces/global-floating-action-button/.changeset/funny-jars-itch.md b/workspaces/global-floating-action-button/.changeset/funny-jars-itch.md new file mode 100644 index 000000000..ac324bb95 --- /dev/null +++ b/workspaces/global-floating-action-button/.changeset/funny-jars-itch.md @@ -0,0 +1,5 @@ +--- +'@red-hat-developer-hub/backstage-plugin-global-floating-action-button': patch +--- + +created dynamic fab to be integrated in the RHDH app diff --git a/workspaces/global-floating-action-button/plugins/global-floating-action-button/README.md b/workspaces/global-floating-action-button/plugins/global-floating-action-button/README.md index 15d2acf12..b1b997771 100644 --- a/workspaces/global-floating-action-button/plugins/global-floating-action-button/README.md +++ b/workspaces/global-floating-action-button/plugins/global-floating-action-button/README.md @@ -10,6 +10,56 @@ This plugin has been added to the example app in this workspace, meaning it can ### Installation +#### Installing as a dynamic plugin? + +The sections below are relevant for static plugins. If the plugin is expected to be installed as a dynamic one: + +- Follow https://github.com/redhat-developer/rhdh/blob/main/docs/dynamic-plugins/installing-plugins.md +- Add content of `app-config.dynamic.yaml` into `app-config.local.yaml`. +- To configure a plugin as a Floating Action Button (FAB), you need to specify the `global.floatingactionbutton/component` mount point in your plugin configuration, as shown below using the bulk-import plugin as an example: + + ```yaml + dynamicPlugins: + frontend: + red-hat-developer-hub.backstage-plugin-bulk-import: + # start of fab config + mountPoints: + - mountPoint: global.floatingactionbutton/component + config: + slot: 'page-end' + icon: bulkImportIcon + label: 'Bulk import' + toolTip: 'Register multiple repositories in bulk' + to: /bulk-import/repositories + # end of fab config + appIcons: + - name: bulkImportIcon + importName: BulkImportIcon + dynamicRoutes: + - path: /bulk-import/repositories + importName: BulkImportPage + menuItem: + icon: bulkImportIcon + text: Bulk import + ``` + +- To configure a Floating Action Button (FAB) that opens an external link, specify the `global.floatingactionbutton/component` mount point in the `backstage-plugin-global-floating-action-button` plugin, as shown below: + + ```yaml + dynamicPlugins: + frontend: + red-hat-developer-hub.backstage-plugin-global-floating-action-button: + mountPoints: + - mountPoint: application/provider + importName: DynamicGlobalFloatingActionButton + - mountPoint: global.floatingactionbutton/component + config: + icon: github + label: 'Git' + toolTip: 'Github' + to: https://github.com/redhat-developer/rhdh-plugins + ``` + #### Procedure 1. Install the Global floating action button plugin using the following command: @@ -29,7 +79,8 @@ This plugin has been added to the example app in this workspace, meaning it can export const Root = ({ children }: PropsWithChildren<{}>) => ( - ... /* highlight-add-start */ + {...} + {/* highlight-add-start */} - /* highlight-add-end */ ... + {/* highlight-add-end */} + {...} ); ``` diff --git a/workspaces/global-floating-action-button/plugins/global-floating-action-button/app-config.dynamic.yaml b/workspaces/global-floating-action-button/plugins/global-floating-action-button/app-config.dynamic.yaml new file mode 100644 index 000000000..20a22c657 --- /dev/null +++ b/workspaces/global-floating-action-button/plugins/global-floating-action-button/app-config.dynamic.yaml @@ -0,0 +1,6 @@ +dynamicPlugins: + frontend: + red-hat-developer-hub.backstage-plugin-global-floating-action-button: + mountPoints: + - mountPoint: application/provider + importName: DynamicGlobalFloatingActionButton diff --git a/workspaces/global-floating-action-button/plugins/global-floating-action-button/dev/ExampleComponent/ExampleComponent.tsx b/workspaces/global-floating-action-button/plugins/global-floating-action-button/dev/ExampleComponent/ExampleComponent.tsx index 6cb0da340..1119ffa2e 100644 --- a/workspaces/global-floating-action-button/plugins/global-floating-action-button/dev/ExampleComponent/ExampleComponent.tsx +++ b/workspaces/global-floating-action-button/plugins/global-floating-action-button/dev/ExampleComponent/ExampleComponent.tsx @@ -14,10 +14,7 @@ * limitations under the License. */ -import React from 'react'; -import AddIcon from '@mui/icons-material/Add'; -import GitIcon from '@mui/icons-material/GitHub'; -import MenuIcon from '@mui/icons-material/Menu'; +import * as React from 'react'; import Typography from '@mui/material/Typography'; import Grid from '@mui/material/Grid'; @@ -29,12 +26,15 @@ import { ContentHeader, HeaderLabel, SupportButton, - GitHubIcon, } from '@backstage/core-components'; import { ExampleFetchComponent } from './ExampleFetchComponent'; -import { GlobalFloatingActionButton, Slot } from '../../src'; +import { FloatingActionButton, GlobalFloatingActionButton } from '../../src'; -export const ExampleComponent = () => ( +export const ExampleComponent = ({ + floatingButtons, +}: { + floatingButtons?: FloatingActionButton[]; +}) => (
( - , - label: 'Git repo', - showLabel: true, - to: 'https://github.com/xyz', - toolTip: 'Git', - }, - - { - color: 'info', - label: 'Quay', - to: 'https://quay.io', - toolTip: 'Quay', - icon: '', - }, - { - slot: Slot.BOTTOM_LEFT, - color: 'success', - icon: , - label: 'Add', - toolTip: 'Add', - to: '/test-global-floating-action', - priority: 100, - }, - { - slot: Slot.BOTTOM_LEFT, - color: 'success', - label: 'Github', - icon: , - toolTip: 'Github', - to: 'https://github.com/xyz', - priority: 200, - visibleOnPaths: ['/test-global-floating-action'], - }, - { - color: 'success', - icon: , - label: 'Menu', - toolTip: 'Menu', - to: 'https://github.com/xyz', - priority: 200, - excludeOnPaths: ['/test-global-floating-action'], - }, - ]} - /> + ); diff --git a/workspaces/global-floating-action-button/plugins/global-floating-action-button/dev/ExampleComponent/ExampleFetchComponent.tsx b/workspaces/global-floating-action-button/plugins/global-floating-action-button/dev/ExampleComponent/ExampleFetchComponent.tsx index 1b524a7ce..3d404287e 100644 --- a/workspaces/global-floating-action-button/plugins/global-floating-action-button/dev/ExampleComponent/ExampleFetchComponent.tsx +++ b/workspaces/global-floating-action-button/plugins/global-floating-action-button/dev/ExampleComponent/ExampleFetchComponent.tsx @@ -120,6 +120,7 @@ export const DenseTable = ({ users }: DenseTableProps) => { const data = users.map(user => { return { + id: user.name, avatar: ( , + label: 'Git repo', + showLabel: true, + to: 'https://github.com/xyz', + toolTip: 'Git', + }, + + { + color: 'info', + label: 'Quay', + to: 'https://quay.io', + toolTip: 'Quay', + icon: '', + }, + { + slot: Slot.BOTTOM_LEFT, + color: 'success', + icon: , + label: 'Add', + toolTip: 'Add', + to: '/test-global-floating-action', + priority: 100, + }, + { + slot: Slot.BOTTOM_LEFT, + color: 'success', + label: 'Github', + icon: , + toolTip: 'Github', + to: 'https://github.com/xyz', + priority: 200, + visibleOnPaths: ['/test-global-floating-action'], + }, + { + color: 'success', + icon: , + label: 'Menu', + toolTip: 'Menu', + to: 'https://github.com/xyz', + priority: 200, + excludeOnPaths: ['/test-global-floating-action'], + }, +]; + +const createPage = ({ + navTitle, + path, + component, +}: { + navTitle: string; + component: React.ReactElement; + pageTitle: string; + path: string; +}): DevAppPageOptions => { + const scalprumState: ScalprumState = { + initialized: true, + api: { + dynamicRootConfig: { + mountPoints: { + 'global.floatingactionbutton/component': [ + { + staticJSXContent: null, + config: { + color: 'success', + icon: 'github', + label: 'DP: Git repo', + showLabel: true, + to: 'https://github.com/xyz', + toolTip: 'Git', + }, + }, + { + staticJSXContent: null, + config: { + color: 'info', + label: 'Quay', + to: 'https://quay.io', + toolTip: 'Quay', + icon: '', + }, + }, + { + staticJSXContent: null, + config: { + slot: 'bottom-left', + color: 'success', + label: 'Github', + icon: 'github', + toolTip: 'Github', + to: 'https://github.com/xyz', + priority: 200, + visibleOnPaths: ['/test-global-floating-action-3'], + }, + }, + ], + }, + }, + }, + config: {}, + pluginStore: new PluginStore(), + }; + + const pageContent = ( + + + {component} + + ); + + return { + element: pageContent, + title: navTitle, + path, + }; +}; createDevApp() .addPage({ - element: , + element: , title: 'Page 1', path: '/test-global-floating-action', }) .addPage({ - element: , + element: , title: 'Page 2', path: '/test-global-floating-action-2', }) + .addPage( + createPage({ + navTitle: 'Page 3', + pageTitle: 'Page 3', + path: '/test-global-floating-action-3', + component: , + }), + ) + .addPage( + createPage({ + navTitle: 'Page 4', + pageTitle: 'Page 4', + path: '/test-global-floating-action-4', + component: , + }), + ) .render(); diff --git a/workspaces/global-floating-action-button/plugins/global-floating-action-button/package.json b/workspaces/global-floating-action-button/plugins/global-floating-action-button/package.json index 1039f594f..34a4ac09a 100644 --- a/workspaces/global-floating-action-button/plugins/global-floating-action-button/package.json +++ b/workspaces/global-floating-action-button/plugins/global-floating-action-button/package.json @@ -39,6 +39,7 @@ "@mui/icons-material": "^5.15.17", "@mui/material": "^5.15.17", "@mui/styles": "5.16.13", + "@scalprum/react-core": "0.9.3", "classnames": "^2.5.1", "react-use": "^17.2.4" }, @@ -49,6 +50,7 @@ "devDependencies": { "@backstage/cli": "^0.28.0", "@backstage/dev-utils": "^1.1.2", + "@openshift/dynamic-plugin-sdk": "5.0.1", "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0", "react": "^16.13.1 || ^17.0.0 || ^18.0.0" diff --git a/workspaces/global-floating-action-button/plugins/global-floating-action-button/report.api.md b/workspaces/global-floating-action-button/plugins/global-floating-action-button/report.api.md index dff798667..ffca41d41 100644 --- a/workspaces/global-floating-action-button/plugins/global-floating-action-button/report.api.md +++ b/workspaces/global-floating-action-button/plugins/global-floating-action-button/report.api.md @@ -8,6 +8,21 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { JSX as JSX_2 } from 'react'; +// @public +export const DynamicGlobalFloatingActionButton: React.ComponentType; + +// @public +export const dynamicGlobalFloatingActionButtonPlugin: BackstagePlugin< + {}, + {}, + {} +>; + +// @public +export type FABMountPoint = { + config?: FloatingActionButton; +}; + // @public export type FloatingActionButton = { slot?: Slot; diff --git a/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/DynamicGlobalFloatingActionButton.tsx b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/DynamicGlobalFloatingActionButton.tsx new file mode 100644 index 000000000..09cf506bb --- /dev/null +++ b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/DynamicGlobalFloatingActionButton.tsx @@ -0,0 +1,36 @@ +/* + * Copyright Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; + +import { useFabMountPoints } from '../hooks/useFabMountPoints'; +import { GlobalFloatingActionButton } from './GlobalFloatingActionButton'; +import { FloatingActionButton } from '../types'; + +/** + * Dynamic Global Floating Action Button + * + * @public + */ +export const DynamicGlobalFloatingActionButton = () => { + const allFabMountPoints = useFabMountPoints(); + + const floatingButtons = (allFabMountPoints || []).map( + fab => fab?.config, + ) as FloatingActionButton[]; + + return ; +}; diff --git a/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/FAB.tsx b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/FAB.tsx index d2db131f3..f23024f53 100644 --- a/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/FAB.tsx +++ b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/FAB.tsx @@ -85,10 +85,27 @@ export const FAB = ({ const newWindow = isExternal && !!/^https?:/.exec(actionButton.to!); const navigateTo = () => actionButton.to && !isExternal ? navigate(actionButton.to) : ''; + + if (!actionButton.label) { + // eslint-disable-next-line no-console + console.warn( + 'Label is missing from your FAB component(s). A label is required for the aria-label attribute.', + ); + } + const labelText = - actionButton.label.length > 20 + (actionButton.label || '').length > 20 ? `${actionButton.label.slice(0, actionButton.label.length)}...` : actionButton.label; + + if (!actionButton.icon) { + // eslint-disable-next-line no-console + console.warn( + 'Icon is missing from your FAB component(s). An icon is required to render a FAB button.', + ); + return null; + } + const getColor = () => { if (actionButton.color) { return actionButton.color; @@ -119,7 +136,7 @@ export const FAB = ({ size={size || actionButton.size || 'medium'} color={getColor()} aria-label={actionButton.label} - data-testid={actionButton.label + data-testid={(actionButton.label || '') .replace(' ', '-') .toLocaleLowerCase('en-US')} onClick={actionButton.onClick || navigateTo} diff --git a/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/FABWithSubmenu.tsx b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/FABWithSubmenu.tsx index a48256cf3..efcf691e6 100644 --- a/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/FABWithSubmenu.tsx +++ b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/FABWithSubmenu.tsx @@ -30,7 +30,10 @@ import { FloatingActionButton, Slot } from '../types'; const useStyles = makeStyles(theme => ({ button: { paddingTop: '10px', - color: theme.palette.grey[500], + color: + theme && Object.keys(theme).length > 0 + ? theme.palette.grey[500] + : '#9e9e9e', }, menuButtonStyle: { color: '#1f1f1f', diff --git a/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/FloatingButton.tsx b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/FloatingButton.tsx index 261800280..fb58325f9 100644 --- a/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/FloatingButton.tsx +++ b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/FloatingButton.tsx @@ -32,13 +32,14 @@ const useStyles = makeStyles(theme => ({ gap: '10px', }, 'page-end': { - bottom: theme.spacing(2), - right: theme.spacing(2), + bottom: theme && Object.keys(theme).length > 0 ? theme?.spacing(2) : '16px', + right: theme && Object.keys(theme).length > 0 ? theme?.spacing(2) : '16px', alignItems: 'end', }, 'bottom-left': { - bottom: theme.spacing(2), - paddingLeft: theme.spacing(2), + bottom: theme && Object.keys(theme).length > 0 ? theme?.spacing(2) : '16px', + paddingLeft: + theme && Object.keys(theme).length > 0 ? theme?.spacing(2) : '16px', alignItems: 'start', }, })); diff --git a/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/index.ts b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/index.ts index ab7450b12..b2431d6ed 100644 --- a/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/index.ts +++ b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/components/index.ts @@ -14,3 +14,4 @@ * limitations under the License. */ export { GlobalFloatingActionButton } from './GlobalFloatingActionButton'; +export { DynamicGlobalFloatingActionButton } from './DynamicGlobalFloatingActionButton'; diff --git a/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/hooks/useFabMountPoints.ts b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/hooks/useFabMountPoints.ts new file mode 100644 index 000000000..6d197308d --- /dev/null +++ b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/hooks/useFabMountPoints.ts @@ -0,0 +1,39 @@ +/* + * Copyright Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useScalprum } from '@scalprum/react-core'; + +import { FABMountPoint } from '../types'; + +interface ScalprumState { + api?: { + dynamicRootConfig?: { + mountPoints?: { + 'global.floatingactionbutton/component': FABMountPoint[]; + }; + }; + }; +} + +export const useFabMountPoints = (): FABMountPoint[] | undefined => { + const scalprum = useScalprum(); + const fabMountPoints = + scalprum?.api?.dynamicRootConfig?.mountPoints?.[ + 'global.floatingactionbutton/component' + ]; + + return fabMountPoints; +}; diff --git a/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/plugin.test.ts b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/plugin.test.ts index 954a9202f..e18f6b450 100644 --- a/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/plugin.test.ts +++ b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/plugin.test.ts @@ -13,10 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { globalFloatingActionButtonPlugin } from './plugin'; + +import { + dynamicGlobalFloatingActionButtonPlugin, + globalFloatingActionButtonPlugin, +} from './plugin'; describe('global-floating-action-button', () => { it('should export plugin', () => { expect(globalFloatingActionButtonPlugin).toBeDefined(); }); }); + +describe('dynamic-global-floating-action-button', () => { + it('should export the dynamic plugin', () => { + expect(dynamicGlobalFloatingActionButtonPlugin).toBeDefined(); + }); +}); diff --git a/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/plugin.ts b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/plugin.ts index 231e9bf03..42d77dcc4 100644 --- a/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/plugin.ts +++ b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/plugin.ts @@ -28,6 +28,15 @@ export const globalFloatingActionButtonPlugin = createPlugin({ id: 'global-floating-action-button', }); +/** + * Dynamic Global Floating Action Button Plugin + * + * @public + */ +export const dynamicGlobalFloatingActionButtonPlugin = createPlugin({ + id: 'dynamic-global-floating-action-button', +}); + /** * Global Floating Action Button * @@ -45,3 +54,21 @@ export const GlobalFloatingActionButton = }, }), ); + +/** + * Dynamic Global Floating Action Button + * + * @public + */ +export const DynamicGlobalFloatingActionButton: React.ComponentType = + dynamicGlobalFloatingActionButtonPlugin.provide( + createComponentExtension({ + name: 'DynamicGlobalFloatingActionButton', + component: { + lazy: () => + import('./components/DynamicGlobalFloatingActionButton').then( + m => m.DynamicGlobalFloatingActionButton, + ), + }, + }), + ); diff --git a/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/types.ts b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/types.ts index bc4747a24..30fe20473 100644 --- a/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/types.ts +++ b/workspaces/global-floating-action-button/plugins/global-floating-action-button/src/types.ts @@ -67,3 +67,12 @@ export type FloatingActionButtonWithPositions = Array<{ slot: Slot; actions: FloatingActionButton[]; }>; + +/** + * FAB Mount Point + * + * @public + */ +export type FABMountPoint = { + config?: FloatingActionButton; +}; diff --git a/workspaces/global-floating-action-button/yarn.lock b/workspaces/global-floating-action-button/yarn.lock index 7155063df..6f6c65c1e 100644 --- a/workspaces/global-floating-action-button/yarn.lock +++ b/workspaces/global-floating-action-button/yarn.lock @@ -9063,6 +9063,20 @@ __metadata: languageName: node linkType: hard +"@openshift/dynamic-plugin-sdk@npm:5.0.1, @openshift/dynamic-plugin-sdk@npm:^5.0.1": + version: 5.0.1 + resolution: "@openshift/dynamic-plugin-sdk@npm:5.0.1" + dependencies: + lodash: ^4.17.21 + semver: ^7.3.7 + uuid: ^8.3.2 + yup: ^0.32.11 + peerDependencies: + react: ^17 || ^18 + checksum: 66e54691ac257cee70b83e627d8fa13c1b0951cc322da0b7c0e2511b9467a9adcf59290ce9250a8ed1de9f98870d6100195afe5dce49ad9b88cf4fc3c991ad4e + languageName: node + linkType: hard + "@opentelemetry/api@npm:^1.3.0, @opentelemetry/api@npm:^1.4.0": version: 1.9.0 resolution: "@opentelemetry/api@npm:1.9.0" @@ -9763,6 +9777,8 @@ __metadata: "@mui/icons-material": ^5.15.17 "@mui/material": ^5.15.17 "@mui/styles": 5.16.13 + "@openshift/dynamic-plugin-sdk": 5.0.1 + "@scalprum/react-core": 0.9.3 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^14.0.0 classnames: ^2.5.1 @@ -10169,6 +10185,30 @@ __metadata: languageName: node linkType: hard +"@scalprum/core@npm:^0.8.1": + version: 0.8.1 + resolution: "@scalprum/core@npm:0.8.1" + dependencies: + "@openshift/dynamic-plugin-sdk": ^5.0.1 + tslib: ^2.6.2 + checksum: 581631848bda2081dfe797c4c4326b442ce086d69117cc1eb74c18d345124825d87f570d09e8edaaa132d32a7720db0e728971834f1509aca9349aff21246a52 + languageName: node + linkType: hard + +"@scalprum/react-core@npm:0.9.3": + version: 0.9.3 + resolution: "@scalprum/react-core@npm:0.9.3" + dependencies: + "@openshift/dynamic-plugin-sdk": ^5.0.1 + "@scalprum/core": ^0.8.1 + lodash: ^4.17.0 + peerDependencies: + react: ">=16.8.0 || >=17.0.0 || ^18.0.0" + react-dom: ">=16.8.0 || >=17.0.0 || ^18.0.0" + checksum: 19c29a54e25c8025b668a96291741ce4b68dc0c87684cc39c260fc29aa2e0fc0d3e01266e0b5f64a290607e3df8d766539b619d23b756e2d09534b37034c313c + languageName: node + linkType: hard + "@scarf/scarf@npm:=1.4.0": version: 1.4.0 resolution: "@scarf/scarf@npm:1.4.0" @@ -12606,6 +12646,13 @@ __metadata: languageName: node linkType: hard +"@types/lodash@npm:^4.14.175": + version: 4.17.14 + resolution: "@types/lodash@npm:4.17.14" + checksum: 2dbeaff92b31cb523f6bc4bb99a3d8c88fbb001d54f2367a888add85784fb213744a9b1600e1e98b6790ab191fdb6ec839eb0e3d63fcf6fb6cf1ebe4c3d21149 + languageName: node + linkType: hard + "@types/long@npm:^4.0.0": version: 4.0.2 resolution: "@types/long@npm:4.0.2" @@ -23566,7 +23613,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:4.17.21, lodash@npm:^4.15.0, lodash@npm:^4.16.4, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:^4.7.0, lodash@npm:~4.17.15, lodash@npm:~4.17.21": +"lodash@npm:4.17.21, lodash@npm:^4.15.0, lodash@npm:^4.16.4, lodash@npm:^4.17.0, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:^4.7.0, lodash@npm:~4.17.15, lodash@npm:~4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 @@ -25110,6 +25157,13 @@ __metadata: languageName: node linkType: hard +"nanoclone@npm:^0.2.1": + version: 0.2.1 + resolution: "nanoclone@npm:0.2.1" + checksum: 96b2954e22f70561f41e20d69856266c65583c2a441dae108f1dc71b716785d2c8038dac5f1d5e92b117aed3825f526b53139e2e5d6e6db8a77cfa35b3b8bf40 + languageName: node + linkType: hard + "nanoid@npm:^3.3.7": version: 3.3.8 resolution: "nanoid@npm:3.3.8" @@ -27502,7 +27556,7 @@ __metadata: languageName: node linkType: hard -"property-expr@npm:^2.0.5": +"property-expr@npm:^2.0.4, property-expr@npm:^2.0.5": version: 2.0.6 resolution: "property-expr@npm:2.0.6" checksum: 89977f4bb230736c1876f460dd7ca9328034502fd92e738deb40516d16564b850c0bbc4e052c3df88b5b8cd58e51c93b46a94bea049a3f23f4a022c038864cab @@ -29442,7 +29496,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.6.3, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0": +"semver@npm:7.6.3, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0": version: 7.6.3 resolution: "semver@npm:7.6.3" bin: @@ -33229,6 +33283,21 @@ __metadata: languageName: node linkType: hard +"yup@npm:^0.32.11": + version: 0.32.11 + resolution: "yup@npm:0.32.11" + dependencies: + "@babel/runtime": ^7.15.4 + "@types/lodash": ^4.14.175 + lodash: ^4.17.21 + lodash-es: ^4.17.21 + nanoclone: ^0.2.1 + property-expr: ^2.0.4 + toposort: ^2.0.2 + checksum: 43a16786b47cc910fed4891cebdd89df6d6e31702e9462e8f969c73eac88551ce750732608012201ea6b93802c8847cb0aa27b5d57370640f4ecf30f9f97d4b0 + languageName: node + linkType: hard + "yup@npm:^1.0.0": version: 1.5.0 resolution: "yup@npm:1.5.0"