Skip to content

Commit

Permalink
Merge pull request #231 from FNNDSC/next
Browse files Browse the repository at this point in the history
Bug fixes and Plugin Versions content
  • Loading branch information
zrthxn authored Aug 6, 2021
2 parents 38f9b37 + 83878df commit 4813215
Show file tree
Hide file tree
Showing 11 changed files with 669 additions and 745 deletions.
23 changes: 11 additions & 12 deletions src/components/Developers/components/Instructions/Instructions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const Instructions = () => (
<h1 className="instructions-header">
Get Started - 4 Simple Steps
{' '}
<a className="instructions-source" href="http://bit.ly/2KghHdY">[source]</a>
<a className="instructions-source" href="https://github.com/FNNDSC/cookiecutter-chrisapp/wiki/Quickstart">[source]</a>
</h1>
<div className="instructions-steps">
<div className="instructions-step">
Expand Down Expand Up @@ -44,7 +44,7 @@ const Instructions = () => (
<ul>
<li>
<a
href="http://bit.ly/2Iih52m"
href="https://github.com/FNNDSC/cookiecutter-chrisapp/wiki/Quickstart#1-prerequisites"
rel="noopener noreferrer"
target="_blank"
>
Expand All @@ -53,7 +53,7 @@ const Instructions = () => (
</li>
<li>
<a
href="http://bit.ly/2KghHdY"
href="https://github.com/FNNDSC/cookiecutter-chrisapp/wiki/Quickstart"
rel="noopener noreferrer"
target="_blank"
>
Expand Down Expand Up @@ -133,7 +133,7 @@ const Instructions = () => (
<h3>
Create a new automated build and repository on your
{' '}
<a href="https://dockr.ly/2K2pnRF">Docker Hub</a>
<a href="https://hub.docker.com/">Docker Hub</a>
{' '}
account.
</h3>
Expand All @@ -151,7 +151,7 @@ const Instructions = () => (
<h3>
For more information on Automated Builds, visit the
{' '}
<a href="https://dockr.ly/2tmNDDz">Docker build documentation</a>
<a href="https://docs.docker.com/docker-hub/builds/">Docker build documentation</a>
.
</h3>
<h3>
Expand All @@ -169,7 +169,7 @@ const Instructions = () => (
<h3>
Look at this
{' '}
<a href="http://bit.ly/2yzbRzF">
<a href="https://github.com/FNNDSC/pl-simplefsapp">
simple
<strong>fs</strong>
{' '}
Expand All @@ -178,7 +178,7 @@ const Instructions = () => (
{' '}
or this
{' '}
<a href="http://bit.ly/2KbHosS">
<a href="https://github.com/FNNDSC/pl-simpledsapp">
simple
<strong>ds</strong>
{' '}
Expand All @@ -199,12 +199,11 @@ const Instructions = () => (
Once you
&apos;
ve developed and properly tested your plugin app
consult the
consult the wiki to learn
{' '}
<a href="http://bit.ly/2ltTJ0w">wiki</a>
{' '}
to learn how to register it to
ChRIS.
<a href="https://github.com/FNNDSC/cookiecutter-chrisapp/wiki/Register-a-new-plugin-app-with-the-ChRIS-store-API">
how to register it to ChRIS.
</a>
</h3>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Navbar/components/Search/Search.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const Search = ({
onChange={onChange}
autoComplete="off"
onKeyDown={(e) => {
if (e.key === 'Enter' && value.length >= 3 && !autoCompleteData.length) {
if (e.key === 'Enter' && value.length >= 3) {
onSearch(value, 'ENTER');
setShowAutoComplete(false);
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Notification/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const Notification = ({ position, variant, message, onClose, closeable, t

Notification.propTypes = {
position: PropTypes.string.isRequired,
message: PropTypes.string.isRequired,
message: PropTypes.string,
variant: PropTypes.string,
closeable: PropTypes.bool,
onClose: PropTypes.func,
Expand Down
142 changes: 77 additions & 65 deletions src/components/Plugin/Plugin.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { Component } from 'react';
import { Badge, Grid, GridItem, Split, SplitItem, Button } from '@patternfly/react-core';
import { StarIcon } from '@patternfly/react-icons';
import PropTypes from 'prop-types';
import Client from '@fnndsc/chrisstoreapi';
import Client, { Plugin } from '@fnndsc/chrisstoreapi';

import LoadingPlugin from './components/LoadingPlugin/LoadingPlugin';
import PluginBody from './components/PluginBody/PluginBody';
Expand All @@ -15,46 +15,62 @@ import HttpApiCallError from '../../errors/HttpApiCallError';

import './Plugin.css';

export class Plugin extends Component {
/**
* View a plugin by plugin ID.
*/
export class PluginView extends Component {
constructor(props) {
super(props);

this.mounted = false;

const { pluginData, isFavorite } = props;
this.state = {
pluginData,
pluginData: undefined,
star: undefined,
loading: true,
star: isFavorite || undefined,
errors: [],
};

const storeURL = process.env.REACT_APP_STORE_URL;
const auth = { token: props.store.get('authToken') };
this.client = new Client(storeURL, auth);

this.fetchPluginData = this.fetchPluginData.bind(this);
}

/**
* Fetch a plugin by ID, from URL params.
* Then fetch other plugins which have the same name as versions.
* Set stars if user is logged in.
*/
async componentDidMount() {
let { pluginData } = this.state;

if (!pluginData) {
pluginData = await this.fetchPluginData();
}

this.setState({ pluginData, loading: false });
if (this.isLoggedIn()) {
this.fetchIsPluginStarred(pluginData);
// eslint-disable-next-line react/destructuring-assignment
const { pluginId } = this.props.match.params;
try {
const plugin = await this.fetchPlugin(pluginId);
const versions = await this.fetchPluginVersions(plugin.data.name);

let star;
if (this.isLoggedIn())
star = await this.fetchIsPluginStarred(plugin.data);

this.setState({
loading: false,
pluginData: {
...plugin.data,
url: plugin.url,
versions
},
star,
});
} catch (error) {
this.setState((prev) => ({
loading: false,
errors: [ ...prev.errors, error ]
}));
}
}

showNotifications = (error) => {
let { errors } = this.state;
errors = [ ...errors, error.message ]
this.setState({
errors
})
this.setState((prev) => ({
errors: [ ...prev.errors, error ]
}));
}

// eslint-disable-next-line react/destructuring-assignment
Expand All @@ -65,9 +81,13 @@ export class Plugin extends Component {

onStarClicked = () => {
if (this.isLoggedIn()) {
return this.isFavorite() ? this.unfavPlugin() : this.favPlugin();
if (this.isFavorite())
this.unfavPlugin();
else
this.favPlugin();
}
return Promise.resolve();
else
this.showNotifications(new Error('Login required to favorite this plugin.'))
}

favPlugin = async () => {
Expand Down Expand Up @@ -119,27 +139,35 @@ export class Plugin extends Component {
return <StarIcon name={name} className={className} onClick={this.onStarClicked} />;
}

async fetchPluginData() {
/**
* Fetch a plugin by ID
* @param {string} pluginId
* @returns {Promise} Plugin
*/
async fetchPlugin(pluginId) {
// eslint-disable-next-line react/destructuring-assignment
const { pluginId } = this.props.match.params;
return this.client.getPlugin(parseInt(pluginId, 10));
}

try {
const plugin = await this.client.getPlugin(parseInt(pluginId, 10));
return { ...plugin.data, url: plugin.url };
} catch (e) {
this.showNotifications(new HttpApiCallError(e));
return e
}
/**
* Fetch all versions of a plugin by name.
* @param {string} name Plugin name
* @returns Promise => void
*/
async fetchPluginVersions(name) {
const versions = await this.client.getPlugins({ limit: 10e6, name_exact: name });
const firstplg = await this.client.getPlugin(parseInt(versions.data[0].id, 10));
return [
{ ...versions.data[0], url: firstplg.url },
...versions.data.slice(1)
]
}

async fetchIsPluginStarred({ name }) {
try {
const response = await this.client.getPluginStars({ plugin_name: name });
if (response.data.length > 0)
this.setState({ star: response.data[0] });
} catch(error) {
this.showNotifications(new HttpApiCallError(error));
}
const response = await this.client.getPluginStars({ plugin_name: name });
if (response.data.length > 0)
return response.data[0];
return undefined;
}

render() {
Expand Down Expand Up @@ -216,7 +244,6 @@ export class Plugin extends Component {
);
}

const { className } = this.props;
return (
<>
{
Expand All @@ -234,7 +261,7 @@ export class Plugin extends Component {
/>
))
}
<div className={`plugin ${className}`}>
<div className="plugin">
{container}
</div>
</>
Expand All @@ -244,36 +271,21 @@ export class Plugin extends Component {
}

Plugin.propTypes = {
store: PropTypes.objectOf(PropTypes.object),
match: PropTypes.shape({
params: PropTypes.shape({
plugin: PropTypes.string,
}),
}),
pluginData: PropTypes.shape({
plugin: PropTypes.string,
pluginURL: PropTypes.string,
authorURL: PropTypes.string,
title: PropTypes.string,
id: PropTypes.number,
description: PropTypes.string,
dock_image: PropTypes.string,
modification_date: PropTypes.string,
authors: PropTypes.arrayOf(PropTypes.string),
version: PropTypes.string,
}),
className: PropTypes.string,
store: PropTypes.objectOf(PropTypes.object),
})
})
};

Plugin.defaultProps = {
store: new Map(),
match: {
params: {
plugin: undefined,
},
},
pluginData: null,
className: '',
store: new Map(),
}
}
};

export default ChrisStore.withStore(Plugin);
export default ChrisStore.withStore(PluginView);
Loading

0 comments on commit 4813215

Please sign in to comment.