diff --git a/src/components/Plugins/Plugins.jsx b/src/components/Plugins/Plugins.jsx index 1748db8c..247673be 100644 --- a/src/components/Plugins/Plugins.jsx +++ b/src/components/Plugins/Plugins.jsx @@ -9,7 +9,7 @@ import { Grid, GridItem, Split, - SplitItem + SplitItem, } from "@patternfly/react-core"; import { CaretDownIcon } from '@patternfly/react-icons'; @@ -26,6 +26,7 @@ import { removeEmail } from '../../utils/common'; import './Plugins.css'; + const CATEGORIES = ['FreeSurfer', 'MRI', 'Segmentation']; /** @@ -49,12 +50,14 @@ export class Plugins extends Component { isSortOpen: false, error: null, plugins: new PluginMetaList(), + sortedPlugins: null, paginationLimit: 0, paginationOffset: 0, categories, selectedCategory: null, starsByPlugin: {}, }; + } /** @@ -79,6 +82,44 @@ export class Plugins extends Component { } } + /** + * Sort plugins by name, creation date or authors. + * + */ +handleSortPlugins = (sortType)=> { + this.setState({sortedPlugins: null}) + const { plugins} = this.state; + + const sortedPluginsList = [...plugins.data].sort((a,b) => { + if (typeof a[sortType] !== 'number') return a[sortType].localeCompare(b[sortType]) + return b[sortType] - a[sortType] + }) + + this.setState({ + sortedPlugins: sortedPluginsList + }) +} + + +// eslint-disable-next-line react/sort-comp +// async tester(){ +// // eslint-disable-next-line no-unused-vars +// let test; +// try { +// test = await this.client.getPlugins({ +// limit: 1e6, +// offset: 0, +// name_title_category: null, +// }); +// } catch (error) { +// // this.showNotifications(new HttpApiCallError(error)); +// console.log(error) + +// } +// return test +// } + + /** * Add a star next to the plugin visually. * (Does not necessarily send to the backend that the plugin is a favorite). @@ -107,8 +148,13 @@ export class Plugins extends Component { * @param name name of category */ handleCategorySelect = (category) => { - this.setState({ loading: true, selectedCategory: category }); - this.refreshPluginList({ category }) + if (category !== null) { + this.refreshPluginList({ category }) + this.setState({ loading: true, selectedCategory: category }); + } else { + this.refreshPluginList() + this.setState({ loading: true, selectedCategory: null }); + } } handleToggleSort = () => { @@ -117,13 +163,6 @@ export class Plugins extends Component { })) } - // eslint-disable-next-line no-unused-vars - handleSortingSelect = (sort) => { - /** - * @todo sort plugins - */ - this.handleToggleSort() - } /** * 1. Fetch the list of plugins based on the url path OR search query. @@ -134,7 +173,7 @@ export class Plugins extends Component { const params = new URLSearchParams(window.location.search) const query = params.get('q'); const { match } = this.props; - + const searchParams = { limit: 20, offset: 0, @@ -158,6 +197,7 @@ export class Plugins extends Component { searchParams.name_title_category = query; let plugins; + try { plugins = await this.client.getPluginMetas(searchParams); } catch (error) { @@ -213,12 +253,12 @@ export class Plugins extends Component { // count the frequency of catplugins which belong to categories // eslint-disable-next-line no-restricted-syntax for (const { category } of catplugins.data) - if (category) + if (category) categories.set( category, categories.has(category) ? categories.get(category) + 1 : 1); - + this.setState({ categories }); } @@ -305,21 +345,37 @@ export class Plugins extends Component { } } - render() { + render() { // convert map into the data structure expected by - const { categories, plugins, loading, error } = this.state; + const { categories, plugins, sortedPlugins, loading, error } = this.state; const { paginationOffset, paginationLimit, isSortOpen, selectedCategory } = this.state; const categoryEntries = Array.from(categories.entries(), ([name, count]) => ({ name, length: count })); + const dropdownItems = [ + this.handleSortPlugins('name')}>Name, + this.handleSortPlugins('creation_date')}>Date created, + this.handleSortPlugins('authors')}>Author, + this.handleSortPlugins('stars')}>Most Liked + ] + const pluginList = new Map() - // eslint-disable-next-line no-restricted-syntax + + if (!sortedPlugins){ + // eslint-disable-next-line no-restricted-syntax for (const plugin of plugins.data) { plugin.authors = removeEmail(plugin.authors.split(',')) pluginList.set(plugin.name, plugin) } + } else { + // eslint-disable-next-line no-restricted-syntax + for (const plugin of sortedPlugins) { + pluginList.set(plugin.name, plugin) + } + } + // Render the pluginList if the plugins have been fetched const PluginListBody = () => { @@ -370,7 +426,6 @@ export class Plugins extends Component { const pluginsCount=plugins.totalCount > 0 ? plugins.totalCount : 0; - return (
{error && ( @@ -434,18 +489,16 @@ export class Plugins extends Component { - Sort by + Sort by: } - dropdownItems={[ - Name - ]} + dropdownItems={dropdownItems} /> @@ -453,9 +506,7 @@ export class Plugins extends Component { - - diff --git a/src/components/Plugins/components/PluginItem/PluginItem.jsx b/src/components/Plugins/components/PluginItem/PluginItem.jsx index 6b7d44e8..f1bd25a2 100644 --- a/src/components/Plugins/components/PluginItem/PluginItem.jsx +++ b/src/components/Plugins/components/PluginItem/PluginItem.jsx @@ -46,7 +46,7 @@ const PluginItem = ({ to={`/author/${authors}`} className="plugin-item-author" > - { authors.join(', ') } + { authors.length > 1 ?? authors.join(', ') }

{ diff --git a/src/components/Plugins/components/PluginsCategories/PluginsCategories.jsx b/src/components/Plugins/components/PluginsCategories/PluginsCategories.jsx index ea041005..e6edc762 100644 --- a/src/components/Plugins/components/PluginsCategories/PluginsCategories.jsx +++ b/src/components/Plugins/components/PluginsCategories/PluginsCategories.jsx @@ -17,7 +17,7 @@ const PluginsCategories = ({ categories, selected, onSelect }) => ( onClick={() => onSelect(name)} onKeyPress={() => {}} > -

{name}
+
{name.charAt(0).toUpperCase()}{name.substring(1)}
{length}
))