Nav: Handle app plugin installation/uninstallation (#63706)

This commit is contained in:
Andres Martinez Gotor 2023-03-02 09:50:01 +01:00 committed by GitHub
parent a4fc8b9fca
commit dc6d0a2bdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 18 deletions

View File

@ -63,8 +63,15 @@ const navTreeSlice = createSlice({
}
}
},
removePluginFromNavTree: (state, action: PayloadAction<{ pluginID: string }>) => {
const navID = 'plugin-page-' + action.payload.pluginID;
const pluginItemIndex = state.findIndex((navItem) => navItem.id === navID);
if (pluginItemIndex > -1) {
state.splice(pluginItemIndex, 1);
}
},
},
});
export const { setStarred, updateDashboardName } = navTreeSlice.actions;
export const { setStarred, removePluginFromNavTree, updateDashboardName } = navTreeSlice.actions;
export const navTreeReducer = navTreeSlice.reducer;

View File

@ -6,6 +6,8 @@ import { locationService } from '@grafana/runtime';
import { Button, HorizontalGroup, ConfirmModal } from '@grafana/ui';
import appEvents from 'app/core/app_events';
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 { trackPluginInstalled, trackPluginUninstalled } from '../../tracking';
@ -15,9 +17,16 @@ type InstallControlsButtonProps = {
plugin: CatalogPlugin;
pluginStatus: PluginStatus;
latestCompatibleVersion?: Version;
setNeedReload: (needReload: boolean) => void;
};
export function InstallControlsButton({ plugin, pluginStatus, latestCompatibleVersion }: InstallControlsButtonProps) {
export function InstallControlsButton({
plugin,
pluginStatus,
latestCompatibleVersion,
setNeedReload,
}: InstallControlsButtonProps) {
const dispatch = useDispatch();
const [queryParams] = useQueryParams();
const location = useLocation();
const { isInstalling, error: errorInstalling } = useInstallStatus();
@ -39,6 +48,9 @@ export function InstallControlsButton({ plugin, pluginStatus, latestCompatibleVe
await install(plugin.id, latestCompatibleVersion?.version);
if (!errorInstalling) {
appEvents.emit(AppEvents.alertSuccess, [`Installed ${plugin.name}`]);
if (plugin.type === 'app') {
setNeedReload(true);
}
}
};
@ -54,6 +66,10 @@ export function InstallControlsButton({ plugin, pluginStatus, latestCompatibleVe
locationService.replace(`${location.pathname}?page=${PluginTabIds.OVERVIEW}`);
}
appEvents.emit(AppEvents.alertSuccess, [`Uninstalled ${plugin.name}`]);
if (plugin.type === 'app') {
dispatch(removePluginFromNavTree({ pluginID: plugin.id }));
setNeedReload(false);
}
}
};

View File

@ -1,6 +1,9 @@
import React from 'react';
import { css } from '@emotion/css';
import React, { useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { config } from '@grafana/runtime';
import { HorizontalGroup, Icon, useStyles2, VerticalGroup } from '@grafana/ui';
import { GetStartedWithPlugin } from '../components/GetStartedWithPlugin';
import { InstallControlsButton } from '../components/InstallControls';
@ -14,8 +17,10 @@ interface Props {
}
export const PluginActions = ({ plugin }: Props) => {
const styles = useStyles2(getStyles);
const isRemotePluginsAvailable = useIsRemotePluginsAvailable();
const latestCompatibleVersion = getLatestCompatibleVersion(plugin?.details?.versions);
const [needReload, setNeedReload] = useState(false);
if (!plugin) {
return null;
@ -32,21 +37,38 @@ export const PluginActions = ({ plugin }: Props) => {
plugin.isCore || plugin.isDisabled || !isInstallControlsEnabled() || hasInstallWarning;
return (
<>
{!isInstallControlsDisabled && (
<>
{isExternallyManaged ? (
<ExternallyManagedButton pluginId={plugin.id} pluginStatus={pluginStatus} />
) : (
<InstallControlsButton
plugin={plugin}
latestCompatibleVersion={latestCompatibleVersion}
pluginStatus={pluginStatus}
/>
)}
</>
<VerticalGroup>
<HorizontalGroup>
{!isInstallControlsDisabled && (
<>
{isExternallyManaged ? (
<ExternallyManagedButton pluginId={plugin.id} pluginStatus={pluginStatus} />
) : (
<InstallControlsButton
plugin={plugin}
latestCompatibleVersion={latestCompatibleVersion}
pluginStatus={pluginStatus}
setNeedReload={setNeedReload}
/>
)}
</>
)}
<GetStartedWithPlugin plugin={plugin} />
</HorizontalGroup>
{needReload && (
<HorizontalGroup>
<Icon name="exclamation-triangle" />
<span className={styles.message}>Refresh the page to see the changes</span>
</HorizontalGroup>
)}
<GetStartedWithPlugin plugin={plugin} />
</>
</VerticalGroup>
);
};
const getStyles = (theme: GrafanaTheme2) => {
return {
message: css`
color: ${theme.colors.text.secondary};
`,
};
};