-
Notifications
You must be signed in to change notification settings - Fork 81
feat(marketplace): integrate plugins-info plugin #1395
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(marketplace): integrate plugins-info plugin #1395
Conversation
|
Important This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior. Changed Packages
|
|
Thank you @ciiay for this PR, looks great. I have some questions:
|
...es/marketplace/plugins/marketplace/src/components/InstalledPlugins/InstalledPluginsTable.tsx
Outdated
Show resolved
Hide resolved
Signed-off-by: Yi Cai <[email protected]>
Signed-off-by: Yi Cai <[email protected]>
Signed-off-by: Yi Cai <[email protected]>
Signed-off-by: Yi Cai <[email protected]>
Signed-off-by: Yi Cai <[email protected]>
Signed-off-by: Yi Cai <[email protected]>
c6035e7 to
a414de9
Compare
Thanks for the review. Uploaded the new screen recording for the fix. |
|
We want to show a single row for plugins(Ex: Marketplace) that have both backend and frontend components
@ShiranHi the backend and frontend components will have different versions, how do we display that ? |
| orderBy = { field: 'name' }, | ||
| orderDirection = 'asc', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These properties are deprecated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
workspaces/marketplace/plugins/marketplace/src/pages/DynamicMarketplacePluginRouter.tsx
Show resolved
Hide resolved
Good point. Sharing a quick heads-up on the “single row per plugin” work and a few pain points. What my PR does now: I group rows by a normalized base name (strip org/prefix and -frontend/-backend/-dynamic), prefer the FE package when both exist, and show that version. This meets the single-row AC but doesn’t look at the plugin extension YAML. Pain points:
Questions and concerns:
|
christoph-jerolimov
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we're almost fine here. Some small details, nothing major and I'm fine if @debsmita1 will merge it.
workspaces/marketplace/plugins/marketplace/src/api/DynamicPluginsInfoClient.ts
Outdated
Show resolved
Hide resolved
...es/marketplace/plugins/marketplace/src/components/InstalledPlugins/InstalledPluginsTable.tsx
Outdated
Show resolved
Hide resolved
...es/marketplace/plugins/marketplace/src/components/InstalledPlugins/InstalledPluginsTable.tsx
Outdated
Show resolved
Hide resolved
...es/marketplace/plugins/marketplace/src/components/InstalledPlugins/InstalledPluginsTable.tsx
Outdated
Show resolved
Hide resolved
Signed-off-by: Yi Cai <[email protected]>
Signed-off-by: Yi Cai <[email protected]>
Signed-off-by: Yi Cai <[email protected]>
Signed-off-by: Yi Cai <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.../marketplace/plugins/marketplace/src/components/InstalledPackages/InstalledPackagesTable.tsx
Outdated
Show resolved
Hide resolved
.../marketplace/plugins/marketplace/src/components/InstalledPackages/InstalledPackagesTable.tsx
Outdated
Show resolved
Hide resolved
.../marketplace/plugins/marketplace/src/components/InstalledPackages/InstalledPackagesTable.tsx
Outdated
Show resolved
Hide resolved
workspaces/marketplace/plugins/marketplace/src/hooks/useInstalledPackagesCount.ts
Show resolved
Hide resolved
.../marketplace/plugins/marketplace/src/components/InstalledPackages/InstalledPackagesTable.tsx
Show resolved
Hide resolved
...es/marketplace/plugins/marketplace/src/components/InstalledPlugins/InstalledPluginsTable.tsx
Outdated
Show resolved
Hide resolved
|
Tested it locally along with redhat-developer/rhdh#3366, and the functionality works fine. |
Changed it to
Updated to |
Signed-off-by: Yi Cai <[email protected]>
Signed-off-by: Yi Cai <[email protected]>
Signed-off-by: Yi Cai <[email protected]>
Signed-off-by: Yi Cai <[email protected]>
|
debsmita1
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Verified that changes made to a package config, updates the yaml file configured in the extensions configuration, and the same is reflected in the edit plugin configuration as well
Screen.Recording.2025-09-25.at.1.29.45.PM.mov
- When updating the package config, users should be directed to the "Installed Packages" tab instead of the package info drawer.
- Since there can be multiple packages with config updates, @ShiranHi could you guide us on how we should handle an alert message in this case?
- Also, we should hide the "Edit Instructions" section if no instructions are available for the package.
- @ShiranHi do you agree that we show the same "Actions" dropdown here like we have on the plugins info drawer (We can address this as part of https://issues.redhat.com/browse/RHIDP-6810)
Let's address the issues in a separate PR
/lgtm
christoph-jerolimov
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a bunch of comment but I think we can merge it now and then take a look into this together:
| "prettier": "^3.4.2", | ||
| "typescript": "~5.3.0" | ||
| "typescript": "~5.3.0", | ||
| "yaml": "^2.8.1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is needed on the workspace level? :)
| "@red-hat-developer-hub/backstage-plugin-marketplace-common": "workspace:^", | ||
| "express": "^4.17.1", | ||
| "express-promise-router": "^4.1.0", | ||
| "yaml": "^2.7.1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
plugins/marketplace-backend/src/installation/FileInstallationStorage.ts is using the yaml package. Please move this back from devDependencies to dependencies.
| queryKey: ['marketplaceApi', 'getPackageByName', namespace, name], | ||
| queryFn: () => marketplaceApi.getPackageByName(namespace, name), | ||
| queryFn: () => marketplaceApi.getPackageByName(namespace!, name!), | ||
| enabled: Boolean(namespace && name), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should have another parameter or another hook for this. I think another hook would be right.
But we can keep it for now.
| const [count, setCount] = useState<number>(0); | ||
| const [loading, setLoading] = useState<boolean>(true); | ||
| const [error, setError] = useState<Error | undefined>(undefined); | ||
| const dynamicPluginInfo = useApi(dynamicPluginsInfoApiRef); | ||
|
|
||
| useEffect(() => { | ||
| const fetchCount = async () => { | ||
| try { | ||
| setLoading(true); | ||
| setError(undefined); | ||
| const plugins = await dynamicPluginInfo.listLoadedPlugins(); | ||
| setCount(plugins.length); | ||
| } catch (err) { | ||
| setError(err as Error); | ||
| setCount(0); | ||
| } finally { | ||
| setLoading(false); | ||
| } | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general we used react-query in this plugin instead of manual state handling
| const fetchData = async ( | ||
| query: Query<InstalledPackageRow>, | ||
| ): Promise<QueryResult<InstalledPackageRow>> => { | ||
| const { page = 0, pageSize = 5 } = query || {}; | ||
|
|
||
| try { | ||
| // Ensure data available; avoid re-fetching on search or pagination | ||
| const installed = installedQuery.data ?? []; | ||
| const packagesResponse = packagesQuery.data ?? { items: [] as any[] }; | ||
|
|
||
| const entitiesByName = new Map( | ||
| (packagesResponse.items ?? []).map(entity => [ | ||
| (entity.metadata?.name ?? '').toLowerCase(), | ||
| entity, | ||
| ]), | ||
| ); | ||
|
|
||
| // Build rows for ALL installed items; if no matching entity, mark missing | ||
| const rows: InstalledPackageRow[] = installed.map(p => { | ||
| const normalized = p.name | ||
| .replace(/[@/]/g, '-') | ||
| .replace(/-dynamic$/, '') | ||
| .replace(/^-+/, '') | ||
| .toLowerCase(); | ||
| const entity = entitiesByName.get(normalized) as any | undefined; | ||
| const rawName = entity | ||
| ? (entity.metadata?.title as string) || | ||
| (entity.metadata?.name as string) | ||
| : getReadableName(p.name); | ||
| const cleanedName = rawName.replace(/\s+(frontend|backend)$/i, ''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is copied but this looks like a lot of code to me that the backstage table is already doing? But maybe I'm wrong in the detail.
Fine for now.
| <Route path="/*" Component={Tabs} /> | ||
| </Routes> | ||
| </ReactQueryProvider> | ||
| <InstallationContextProvider> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can get rid of the InstallationContextProvider or? Doesn't it return null?
| <Route | ||
| path="/packages/:namespace/:name/install" | ||
| Component={MarketplacePackageInstallPage} | ||
| Component={MarketplacePackageEditPage} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, why is it renamed? 😄
| import { MarketplacePackageEditContentLoader } from '../components/MarketplacePackageEditContent'; | ||
|
|
||
| const PackageInstallHeader = () => { | ||
| const PackageEditHeader = () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why renaming things?
| {/* Force remount on navigation within same route to reseed editor */} | ||
| <MarketplacePackageEditContentLoader | ||
| key={`${location.key}-${location.search}`} | ||
| /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤯
| const baseName = packageName | ||
| .replace(/^@Red Hat Developer Hub\/Backstage Plugin\s*/, '') // Red Hat plugins (display names) | ||
| .replace(/^@red-hat-developer-hub\/backstage-plugin-/, '') // Red Hat plugins (package names) | ||
| .replace(/^red-hat-developer-hub-backstage-plugin-/, '') // Red Hat kebab-case | ||
| .replace(/^@backstage-community\/plugin-/, '') // Community plugins | ||
| .replace(/^backstage-community-plugin-/, '') // Community plugins alt | ||
| .replace(/^@backstage\/plugin-/, '') // Official Backstage plugins | ||
| .replace(/^backstage-plugin-/, '') // Generic backstage plugins | ||
| .replace(/-dynamic$/, '') // Remove -dynamic suffix | ||
| .replace(/-frontend$/, '') // Remove -frontend suffix | ||
| .replace(/-backend$/, '') // Remove -backend suffix | ||
| .replace(/^[\s-]+/, '') // Remove leading spaces or dashes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙀
dad9806
into
redhat-developer:main
|
I will address these review comments as part of https://issues.redhat.com/browse/RHIDP-6810 |






Hey, I just made a Pull Request!
For RHIDP-8301
This works with rhdh pr #3366
✔️ Checklist
Test config:
Screen recording of testing on RHDH
Updated on 9/19 (with rhdh pr #3366)
rhidp_8301_new.mp4