insomnia/app/ui/components/settings/plugins.js

196 lines
5.6 KiB
JavaScript
Raw Normal View History

// @flow
import type {Plugin} from '../../../plugins/index';
import {getPlugins} from '../../../plugins/index';
import React from 'react';
import autobind from 'autobind-decorator';
import * as electron from 'electron';
import Button from '../base/button';
import CopyButton from '../base/copy-button';
import {trackEvent} from '../../../analytics/index';
import {reload} from '../../../templating/index';
import installPlugin from '../../../plugins/install';
import HelpTooltip from '../help-tooltip';
import Link from '../base/link';
2017-07-28 22:18:06 +00:00
import {delay} from '../../../common/misc';
@autobind
2017-07-21 18:59:17 +00:00
class Plugins extends React.PureComponent {
state: {
plugins: Array<Plugin>,
npmPluginValue: string,
error: string,
2017-07-28 22:18:06 +00:00
isInstallingFromNpm: boolean,
isRefreshingPlugins: boolean
2017-07-21 18:59:17 +00:00
};
_isMounted: boolean;
2017-07-21 18:59:17 +00:00
constructor (props: any) {
super(props);
this.state = {
plugins: [],
npmPluginValue: '',
error: '',
2017-07-28 22:18:06 +00:00
isInstallingFromNpm: false,
isRefreshingPlugins: false
};
}
_handleClearError () {
this.setState({error: ''});
}
_handleAddNpmPluginChange (e: Event & {target: HTMLButtonElement}) {
this.setState({npmPluginValue: e.target.value});
}
async _handleAddFromNpm (e: Event): Promise<void> {
e.preventDefault();
2017-07-28 22:18:06 +00:00
this.setState({isInstallingFromNpm: true});
2017-07-28 22:18:06 +00:00
const newState = {isInstallingFromNpm: false, error: ''};
try {
await installPlugin(this.state.npmPluginValue);
await this._handleRefreshPlugins();
} catch (err) {
newState.error = err.message;
}
this.setState(newState);
}
2017-07-28 22:18:06 +00:00
_handleOpenDirectory (directory: string): void {
electron.remote.shell.showItemInFolder(directory);
}
2017-07-28 22:18:06 +00:00
async _handleRefreshPlugins (): Promise<void> {
const start = Date.now();
this.setState({isRefreshingPlugins: true});
// Get and reload plugins
const plugins = await getPlugins(true);
reload();
2017-07-28 22:18:06 +00:00
// Delay loading for at least 500ms. UX FTW!
const delta = Date.now() - start;
await delay(500 - delta);
if (this._isMounted) {
this.setState({plugins, isRefreshingPlugins: false});
}
}
async _handleClickRefreshPlugins () {
await this._handleRefreshPlugins();
trackEvent('Plugins', 'Refresh');
}
componentDidMount () {
this._isMounted = true;
this._handleRefreshPlugins();
}
componentWillUnmount () {
this._isMounted = false;
}
render () {
2017-07-28 22:18:06 +00:00
const {plugins, error, isInstallingFromNpm, isRefreshingPlugins} = this.state;
return (
<div>
<p className="notice info no-margin-top">
Plugins is still an experimental feature. Please
{' '}
<Link href="https://insomnia.rest/documentation/support-and-feedback/">
Submit Feedback
</Link> if you have any.
</p>
2017-07-28 22:18:06 +00:00
{plugins.length === 0 ? (
<div className="text-center faint italic pad">No Plugins Added</div>
) : (
<table className="table--fancy table--striped margin-top margin-bottom">
<thead>
<tr>
<th>Name</th>
<th>Version</th>
<th>Folder</th>
</tr>
2017-07-28 22:18:06 +00:00
</thead>
<tbody>
{plugins.map(plugin => (
<tr key={plugin.name}>
<td>
{plugin.name}
{plugin.description && (
<HelpTooltip info className="space-left">{plugin.description}</HelpTooltip>
)}
</td>
<td>{plugin.version}</td>
<td className="no-wrap" style={{width: '10rem'}}>
<CopyButton className="btn btn--outlined btn--super-duper-compact"
title={plugin.directory}
content={plugin.directory}>
Copy Path
</CopyButton>
{' '}
<Button className="btn btn--outlined btn--super-duper-compact"
onClick={this._handleOpenDirectory}
value={plugin.directory}>
Show Folder
</Button>
</td>
</tr>
))}
</tbody>
</table>
)}
{error && (
<div className="notice error text-left margin-bottom">
<button className="pull-right icon" onClick={this._handleClearError}>
<i className="fa fa-times"/>
</button>
{error}
</div>
)}
<form onSubmit={this._handleAddFromNpm}>
<div className="form-row">
<div className="form-control form-control--outlined">
<input onChange={this._handleAddNpmPluginChange}
2017-07-28 22:18:06 +00:00
disabled={isInstallingFromNpm}
type="text"
placeholder="npm-package-name"/>
</div>
<div className="form-control width-auto">
2017-07-28 22:18:06 +00:00
<button className="btn btn--clicky" disabled={isInstallingFromNpm}>
{isInstallingFromNpm && <i className="fa fa-refresh fa-spin space-right"/>}
Install Plugin
</button>
</div>
</div>
</form>
<hr/>
<div className="text-right">
2017-07-28 22:18:06 +00:00
<button type="button"
disabled={isRefreshingPlugins}
className="btn btn--clicky"
onClick={this._handleClickRefreshPlugins}>
Reload Plugin List
2017-07-28 22:18:06 +00:00
{isRefreshingPlugins && (
<i className="fa fa-refresh fa-spin space-left"/>
)}
</button>
</div>
</div>
);
}
}
export default Plugins;