Skip to content

Commit 17e7e5b

Browse files
authored
fix(extensions): improve plugin installation alert message (#1642)
1 parent d798337 commit 17e7e5b

23 files changed

Lines changed: 836 additions & 388 deletions
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@red-hat-developer-hub/backstage-plugin-marketplace': patch
3+
---
4+
5+
- improve plugin installation alert message with link to documentation
6+
- show err message on the drawer when plugin/package content is not available
7+
- show an alert when the dynamicArtifact for a package is missing
Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
dynamicPlugins:
22
frontend:
33
red-hat-developer-hub.backstage-plugin-marketplace:
4+
translationResources:
5+
- importName: marketplaceTranslations
6+
ref: marketplaceTranslationRef
7+
module: Alpha
48
appIcons:
5-
- name: marketplace
6-
importName: MarketplaceIcon
9+
- name: pluginsIcon
10+
importName: PluginsIcon
711
dynamicRoutes:
8-
- path: /extensions/catalog
12+
- path: /extensions
913
importName: DynamicMarketplacePluginRouter
10-
mountPoints:
11-
- mountPoint: application/provider
12-
importName: InstallationContextProvider
13-
- mountPoint: internal.plugins/tab
14-
importName: DynamicMarketplacePluginContent
15-
config:
16-
path: extensions
17-
title: Catalog
14+
menuItem:
15+
icon: pluginsIcon
16+
text: Extensions
17+
textKey: menuItem.extensions
18+
menuItems:
19+
extensions:
20+
parent: default.admin

workspaces/marketplace/plugins/marketplace/report-alpha.api.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,16 @@ readonly "metadata.about": string;
6060
readonly "metadata.highlights": string;
6161
readonly "metadata.category": string;
6262
readonly "metadata.by": string;
63+
readonly "metadata.comma": string;
6364
readonly "metadata.versions": string;
6465
readonly "metadata.pluginNotFound": string;
66+
readonly "metadata.pluginNotAvailable": string;
67+
readonly "metadata.ensureCatalogEntityPlugin": string;
6568
readonly "metadata.publisher": string;
6669
readonly "metadata.supportProvider": string;
6770
readonly "metadata.entryName": string;
6871
readonly "metadata.bySomeone": string;
72+
readonly "metadata.backstageCompatibility": string;
6973
readonly "role.backend": string;
7074
readonly "role.backendModule": string;
7175
readonly "role.frontend": string;
@@ -98,6 +102,8 @@ readonly "install.back": string;
98102
readonly "install.packageUpdated": string;
99103
readonly "install.packageEnabled": string;
100104
readonly "install.packageDisabled": string;
105+
readonly "install.pluginEnabled": string;
106+
readonly "install.pluginDisabled": string;
101107
readonly "install.errors.missingPluginsList": string;
102108
readonly "install.errors.missingPackageItem": string;
103109
readonly "install.errors.missingPackageField": string;
@@ -109,6 +115,7 @@ readonly "installedPackages.table.columns.version": string;
109115
readonly "installedPackages.table.columns.role": string;
110116
readonly "installedPackages.table.columns.name": string;
111117
readonly "installedPackages.table.columns.actions": string;
118+
readonly "installedPackages.table.tooltips.installationDisabled": string;
112119
readonly "installedPackages.table.tooltips.packageProductionDisabled": string;
113120
readonly "installedPackages.table.tooltips.enableActions": string;
114121
readonly "installedPackages.table.tooltips.noDownloadPermissions": string;
@@ -131,6 +138,10 @@ readonly "emptyState.noPluginsDescription": string;
131138
readonly "emptyState.configureBackend": string;
132139
readonly "alert.productionDisabled": string;
133140
readonly "alert.installationDisabled": string;
141+
readonly "alert.missingDynamicArtifact": string;
142+
readonly "alert.missingDynamicArtifactTitle": string;
143+
readonly "alert.missingDynamicArtifactForPlugin": string;
144+
readonly "alert.missingDynamicArtifactTitlePlugin": string;
134145
readonly "alert.extensionsExample": string;
135146
readonly "alert.singlePluginRestart": string;
136147
readonly "alert.multiplePluginRestart": string;
@@ -170,6 +181,8 @@ readonly "package.highlights": string;
170181
readonly "package.dynamicPluginPath": string;
171182
readonly "package.backstageRole": string;
172183
readonly "package.notFound": string;
184+
readonly "package.notAvailable": string;
185+
readonly "package.ensureCatalogEntity": string;
173186
readonly "actions.view": string;
174187
readonly "actions.install": string;
175188
readonly "actions.enable": string;
@@ -186,6 +199,7 @@ readonly "actions.packageCurrentlyDisabled": string;
186199
readonly "actions.installTitle": string;
187200
readonly "actions.editTitle": string;
188201
readonly "tooltips.productionDisabled": string;
202+
readonly "tooltips.missingDynamicArtifact": string;
189203
readonly "tooltips.extensionsDisabled": string;
190204
readonly "tooltips.noPermissions": string;
191205
readonly "supportTypes.certifiedBy": string;
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright The Backstage Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { CodeSnippet, WarningPanel } from '@backstage/core-components';
18+
import {
19+
DYNAMIC_PLUGIN_CONFIG_YAML,
20+
EXTENSIONS_CONFIG_YAML,
21+
ExtensionsStatus,
22+
getErrorMessage,
23+
} from '../utils';
24+
import { useTranslation } from '../hooks/useTranslation';
25+
26+
export const InstallationWarning = ({ configData }: { configData: any }) => {
27+
const { t } = useTranslation();
28+
const errorMessage = getErrorMessage(
29+
configData?.error?.reason,
30+
configData?.error?.message,
31+
t,
32+
);
33+
34+
return (
35+
<>
36+
<WarningPanel
37+
title={errorMessage.title}
38+
severity="info"
39+
message={
40+
<>
41+
{errorMessage.message}
42+
<CodeSnippet
43+
language="yaml"
44+
showLineNumbers
45+
highlightedNumbers={errorMessage?.highlightedLineNumbers}
46+
text={`${
47+
configData?.error?.reason === ExtensionsStatus.INVALID_CONFIG
48+
? DYNAMIC_PLUGIN_CONFIG_YAML
49+
: EXTENSIONS_CONFIG_YAML
50+
}`}
51+
/>
52+
</>
53+
}
54+
/>
55+
<br />
56+
</>
57+
);
58+
};

workspaces/marketplace/plugins/marketplace/src/components/InstalledPackages/InstalledPackagesTable.tsx

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ import { Query, QueryResult } from '@material-table/core';
2727
import { useQuery } from '@tanstack/react-query';
2828

2929
import Box from '@mui/material/Box';
30-
import Typography from '@mui/material/Typography';
31-
import AlertTitle from '@mui/material/AlertTitle';
32-
import Link from '@mui/material/Link';
33-
import Alert from '@mui/material/Alert';
3430
import {
3531
MarketplacePackage,
3632
MarketplacePackageInstallStatus,
@@ -53,9 +49,16 @@ import {
5349
import { useInstallationContext } from '../InstallationContext';
5450
import { useNodeEnvironment } from '../../hooks/useNodeEnvironment';
5551
import { InstalledPluginsDialog } from '../InstalledPluginsDialog';
52+
import { useExtensionsConfiguration } from '../../hooks/useExtensionsConfiguration';
53+
import {
54+
ProductionEnvironmentAlert,
55+
ExtensionsConfigurationAlert,
56+
BackendRestartAlert,
57+
} from '../SharedAlerts';
5658

5759
export const InstalledPackagesTable = () => {
5860
const { t } = useTranslation();
61+
const extensionsConfig = useExtensionsConfiguration();
5962
const { installedPackages } = useInstallationContext();
6063
const nodeEnvironment = useNodeEnvironment();
6164
const [error, setError] = useState<Error | undefined>(undefined);
@@ -174,7 +177,11 @@ export const InstalledPackagesTable = () => {
174177
render: (row: InstalledPackageRow) => {
175178
return (
176179
<Box display="flex" gap={1}>
177-
<EditPackage pkg={row} isProductionEnv={isProductionEnvironment} />
180+
<EditPackage
181+
pkg={row}
182+
isProductionEnv={isProductionEnvironment}
183+
isInstallationEnabled={extensionsConfig.data?.enabled ?? false}
184+
/>
178185
{/* Show it when uninstall functionality is implemented */}
179186
{showUninstall && <UninstallPackage pkg={row} />}
180187
<DownloadPackageYaml
@@ -184,6 +191,7 @@ export const InstalledPackagesTable = () => {
184191
<TogglePackage
185192
pkg={row}
186193
isProductionEnv={isProductionEnvironment}
194+
isInstallationEnabled={extensionsConfig.data?.enabled ?? false}
187195
/>
188196
</Box>
189197
);
@@ -247,6 +255,7 @@ export const InstalledPackagesTable = () => {
247255
(entity?.spec?.version as string | undefined) ??
248256
undefined,
249257
hasEntity: !!entity,
258+
missingDynamicArtifact: !entity?.spec?.dynamicArtifact,
250259
namespace: entity?.metadata?.namespace ?? 'default',
251260
name: entity?.metadata?.name,
252261
} as InstalledPackageRow;
@@ -298,32 +307,19 @@ export const InstalledPackagesTable = () => {
298307
? t('installedPackages.table.emptyMessages.noResults')
299308
: t('installedPackages.table.emptyMessages.noRecords');
300309

310+
const showExtensionsConfigurationAlert =
311+
!isProductionEnvironment && !extensionsConfig.data?.enabled;
312+
301313
return (
302314
<>
303-
{isProductionEnvironment && (
304-
<Alert severity="info" sx={{ mb: '1rem' }}>
305-
<AlertTitle>{t('alert.productionDisabled')}</AlertTitle>
306-
</Alert>
307-
)}
308-
{installedPackagesCount > 0 && (
309-
<Alert severity="info" sx={{ mb: '1rem' }}>
310-
<AlertTitle>{t('alert.backendRestartRequired')}</AlertTitle>
311-
{packageInfo()}
312-
{installedPackagesCount > 1 && (
313-
<Typography component="div" sx={{ pt: '8px' }}>
314-
<Link
315-
component="button"
316-
underline="none"
317-
onClick={() => {
318-
setOpenInstalledPackagesDialog(true);
319-
}}
320-
>
321-
{t('alert.viewPackages')}
322-
</Link>
323-
</Typography>
324-
)}
325-
</Alert>
326-
)}
315+
{isProductionEnvironment && <ProductionEnvironmentAlert />}
316+
{showExtensionsConfigurationAlert && <ExtensionsConfigurationAlert />}
317+
<BackendRestartAlert
318+
count={installedPackagesCount}
319+
itemInfo={packageInfo()}
320+
viewItemsLabel={t('alert.viewPackages')}
321+
onViewItems={() => setOpenInstalledPackagesDialog(true)}
322+
/>
327323

328324
<div
329325
style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: 8 }}

0 commit comments

Comments
 (0)