mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Catalog: Show install error with incompatible version (#65059)
This commit is contained in:
committed by
GitHub
parent
bc5881a051
commit
98778289cb
@@ -103,7 +103,10 @@ export async function getLocalPlugins(): Promise<LocalPlugin[]> {
|
||||
export async function installPlugin(id: string) {
|
||||
// This will install the latest compatible version based on the logic
|
||||
// on the backend.
|
||||
return await getBackendSrv().post(`${API_ROOT}/${id}/install`);
|
||||
return await getBackendSrv().post(`${API_ROOT}/${id}/install`, undefined, {
|
||||
// Error is displayed in the page
|
||||
showErrorAlert: false,
|
||||
});
|
||||
}
|
||||
|
||||
export async function uninstallPlugin(id: string) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { AppEvents } from '@grafana/data';
|
||||
@@ -9,7 +9,7 @@ import { useQueryParams } from 'app/core/hooks/useQueryParams';
|
||||
import { removePluginFromNavTree } from 'app/core/reducers/navBarTree';
|
||||
import { useDispatch } from 'app/types';
|
||||
|
||||
import { useInstallStatus, useUninstallStatus, useInstall, useUninstall } from '../../state/hooks';
|
||||
import { useInstallStatus, useUninstallStatus, useInstall, useUninstall, useUnsetInstall } from '../../state/hooks';
|
||||
import { trackPluginInstalled, trackPluginUninstalled } from '../../tracking';
|
||||
import { CatalogPlugin, PluginStatus, PluginTabIds, Version } from '../../types';
|
||||
|
||||
@@ -33,6 +33,7 @@ export function InstallControlsButton({
|
||||
const { isUninstalling, error: errorUninstalling } = useUninstallStatus();
|
||||
const install = useInstall();
|
||||
const uninstall = useUninstall();
|
||||
const unsetInstall = useUnsetInstall();
|
||||
const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false);
|
||||
const showConfirmModal = () => setIsConfirmModalVisible(true);
|
||||
const hideConfirmModal = () => setIsConfirmModalVisible(false);
|
||||
@@ -43,10 +44,18 @@ export function InstallControlsButton({
|
||||
path: location.pathname,
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
// Remove possible installation errors
|
||||
unsetInstall();
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const onInstall = async () => {
|
||||
trackPluginInstalled(trackingProps);
|
||||
await install(plugin.id, latestCompatibleVersion?.version);
|
||||
if (!errorInstalling) {
|
||||
const result = await install(plugin.id, latestCompatibleVersion?.version);
|
||||
if (!errorInstalling && !('error' in result)) {
|
||||
appEvents.emit(AppEvents.alertSuccess, [`Installed ${plugin.name}`]);
|
||||
if (plugin.type === 'app') {
|
||||
setNeedReload(true);
|
||||
@@ -115,7 +124,7 @@ export function InstallControlsButton({
|
||||
}
|
||||
|
||||
return (
|
||||
<Button disabled={isInstalling} onClick={onInstall}>
|
||||
<Button disabled={isInstalling || errorInstalling} onClick={onInstall}>
|
||||
{isInstalling ? 'Installing' : 'Install'}
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -2,11 +2,11 @@ import { css } from '@emotion/css';
|
||||
import React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import { Alert, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { InstallControlsWarning } from '../components/InstallControls';
|
||||
import { getLatestCompatibleVersion, hasInstallControlWarning } from '../helpers';
|
||||
import { useIsRemotePluginsAvailable } from '../state/hooks';
|
||||
import { useInstallStatus, useIsRemotePluginsAvailable } from '../state/hooks';
|
||||
import { CatalogPlugin, PluginStatus } from '../types';
|
||||
|
||||
interface Props {
|
||||
@@ -16,6 +16,7 @@ interface Props {
|
||||
export const PluginSubtitle = ({ plugin }: Props) => {
|
||||
const isRemotePluginsAvailable = useIsRemotePluginsAvailable();
|
||||
const styles = useStyles2(getStyles);
|
||||
const { error: errorInstalling } = useInstallStatus();
|
||||
if (!plugin) {
|
||||
return null;
|
||||
}
|
||||
@@ -28,6 +29,11 @@ export const PluginSubtitle = ({ plugin }: Props) => {
|
||||
|
||||
return (
|
||||
<div className={styles.subtitle}>
|
||||
{errorInstalling && (
|
||||
<Alert title={'message' in errorInstalling ? errorInstalling.message : ''}>
|
||||
{typeof errorInstalling === 'string' ? errorInstalling : errorInstalling.error}
|
||||
</Alert>
|
||||
)}
|
||||
{plugin?.description && <div>{plugin?.description}</div>}
|
||||
{plugin?.details?.links && plugin.details.links.length > 0 && (
|
||||
<span>
|
||||
|
||||
@@ -87,12 +87,17 @@ export const install = createAsyncThunk(
|
||||
return { id, changes } as Update<CatalogPlugin>;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
if (isFetchError(e)) {
|
||||
return thunkApi.rejectWithValue(e.data);
|
||||
}
|
||||
|
||||
return thunkApi.rejectWithValue('Unknown error.');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export const unsetInstall = createAsyncThunk(`${STATE_PREFIX}/install`, async () => ({}));
|
||||
|
||||
export const uninstall = createAsyncThunk(`${STATE_PREFIX}/uninstall`, async (id: string, thunkApi) => {
|
||||
try {
|
||||
await uninstallPlugin(id);
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useDispatch, useSelector } from 'app/types';
|
||||
import { sortPlugins, Sorters } from '../helpers';
|
||||
import { CatalogPlugin, PluginListDisplayMode } from '../types';
|
||||
|
||||
import { fetchAll, fetchDetails, fetchRemotePlugins, install, uninstall, fetchAllLocal } from './actions';
|
||||
import { fetchAll, fetchDetails, fetchRemotePlugins, install, uninstall, fetchAllLocal, unsetInstall } from './actions';
|
||||
import { setDisplayMode } from './reducer';
|
||||
import {
|
||||
find,
|
||||
@@ -74,6 +74,12 @@ export const useInstall = () => {
|
||||
return (id: string, version?: string, isUpdating?: boolean) => dispatch(install({ id, version, isUpdating }));
|
||||
};
|
||||
|
||||
export const useUnsetInstall = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
return () => dispatch(unsetInstall());
|
||||
};
|
||||
|
||||
export const useUninstall = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user