Files
flipper/desktop/flipper-ui-core/src/chrome/PluginActions.tsx
Michel Weststrate e7f841b6d2 Move flipper plugin from flipper-lib types to flipper-common
Summary: Moved all types related to plugin descriptions from plugin-lib (which handles downloads and such) to flipper-common. The goal of that is to remove all plugin-lib usage from ui-core to server-core, so that the UI itself doesn't do any file operations anymore related to plugins. That will be done in next diffs, this just moves types but no code.

Reviewed By: nikoant, aigoncharov

Differential Revision: D32665064

fbshipit-source-id: 86d908e7264569b0229b09290a891171876c8e00
2021-12-08 04:30:55 -08:00

124 lines
3.1 KiB
TypeScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {
DownloadOutlined,
LoadingOutlined,
PlusOutlined,
} from '@ant-design/icons';
import {Alert, Button} from 'antd';
import {BundledPluginDetails, DownloadablePluginDetails} from 'flipper-common';
import React, {useMemo} from 'react';
import {useCallback} from 'react';
import {useDispatch, useSelector} from 'react-redux';
import {PluginDefinition} from '../plugin';
import {startPluginDownload} from '../reducers/pluginDownloads';
import {loadPlugin, switchPlugin} from '../reducers/pluginManager';
import {
getActiveClient,
getPluginDownloadStatusMap,
} from '../selectors/connections';
import {Layout} from '../ui';
import {ActivePluginListItem} from '../utils/pluginUtils';
export function PluginActions({
activePlugin,
type,
}: {
activePlugin: ActivePluginListItem;
type: 'link' | 'primary';
}) {
switch (activePlugin.status) {
case 'disabled': {
return <EnableButton plugin={activePlugin.definition} type={type} />;
}
case 'uninstalled': {
return <InstallButton plugin={activePlugin.details} type={type} />;
}
case 'unavailable': {
return type === 'primary' ? (
<UnavailabilityAlert reason={activePlugin.reason} />
) : null;
}
default:
return null;
}
}
function EnableButton({
plugin,
type,
}: {
plugin: PluginDefinition;
type: 'link' | 'primary';
}) {
const dispatch = useDispatch();
const client = useSelector(getActiveClient);
const enableOrDisablePlugin = useCallback(() => {
dispatch(switchPlugin({plugin, selectedApp: client?.query?.app}));
}, [dispatch, plugin, client]);
return (
<Button
type={type}
icon={<PlusOutlined />}
onClick={enableOrDisablePlugin}
style={{flexGrow: type == 'primary' ? 1 : 0}}>
Enable Plugin
</Button>
);
}
function UnavailabilityAlert({reason}: {reason: string}) {
return (
<Layout.Container center>
<Alert message={reason} type="warning" />
</Layout.Container>
);
}
function InstallButton({
plugin,
type = 'primary',
}: {
plugin: DownloadablePluginDetails | BundledPluginDetails;
type: 'link' | 'primary';
}) {
const dispatch = useDispatch();
const installPlugin = useCallback(() => {
if (plugin.isBundled) {
dispatch(loadPlugin({plugin, enable: true, notifyIfFailed: true}));
} else {
dispatch(startPluginDownload({plugin, startedByUser: true}));
}
}, [plugin, dispatch]);
const downloads = useSelector(getPluginDownloadStatusMap);
const downloadStatus = useMemo(
() => downloads.get(plugin.id),
[downloads, plugin],
);
return (
<Button
type={type}
disabled={!!downloadStatus}
icon={
downloadStatus ? (
<LoadingOutlined size={16} />
) : (
<DownloadOutlined size={16} />
)
}
onClick={installPlugin}
style={{
flexGrow: type === 'primary' ? 1 : 0,
}}>
Install Plugin
</Button>
);
}