From 6cd4177c6415712dd9a22a959fbf09b8a496882c Mon Sep 17 00:00:00 2001 From: "antonio.bergas" Date: Fri, 28 Apr 2023 14:51:57 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(pluginsFilter):=20added=20drop?= =?UTF-8?q?down=20filter=20for=20plugins=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: antonio.bergas --- .../pluginsFilter/pluginsFilter.tsx | 36 ++++ microsite/src/pages/plugins/index.tsx | 171 +++++++++++++----- .../src/pages/plugins/plugins.module.scss | 35 +++- microsite/src/util/types.ts | 4 + 4 files changed, 202 insertions(+), 44 deletions(-) create mode 100644 microsite/src/components/pluginsFilter/pluginsFilter.tsx create mode 100644 microsite/src/util/types.ts diff --git a/microsite/src/components/pluginsFilter/pluginsFilter.tsx b/microsite/src/components/pluginsFilter/pluginsFilter.tsx new file mode 100644 index 0000000000..19b80b9f14 --- /dev/null +++ b/microsite/src/components/pluginsFilter/pluginsFilter.tsx @@ -0,0 +1,36 @@ +import { ChipCategory } from '@site/src/util/types'; +import React from 'react'; + +type Props = { + categories: ChipCategory[]; + handleChipClick: (name: string) => void; +}; + +const PluginsFilter = ({ categories, handleChipClick }: Props) => { + return ( +
+ +
    + {categories.map(chip => { + return ( +
  • +
    + handleChipClick(chip.name)} + /> + {chip.name} +
    +
  • + ); + })} +
+
+ ); +}; + +export default PluginsFilter; diff --git a/microsite/src/pages/plugins/index.tsx b/microsite/src/pages/plugins/index.tsx index 280a165daa..2349e391fa 100644 --- a/microsite/src/pages/plugins/index.tsx +++ b/microsite/src/pages/plugins/index.tsx @@ -1,13 +1,13 @@ import Link from '@docusaurus/Link'; import Layout from '@theme/Layout'; import clsx from 'clsx'; -import React from 'react'; - +import React, { useState } from 'react'; import { IPluginData, PluginCard } from './_pluginCard'; import pluginsStyles from './plugins.module.scss'; +import { ChipCategory } from '@site/src/util/types'; import { truncateDescription } from '@site/src/util/truncateDescription'; +import PluginsFilter from '@site/src/components/pluginsFilter/pluginsFilter'; -//#region Plugin data import const pluginsContext = require.context( '../../../data/plugins', false, @@ -29,50 +29,135 @@ const plugins = pluginsContext.keys().reduce( plugins.corePlugins.sort((a, b) => a.order - b.order); plugins.otherPlugins.sort((a, b) => a.order - b.order); -//#endregion -const Plugins = () => ( - -
-
-
-

Plugin Marketplace

+const Plugins = () => { + const allCategories: ChipCategory[] = []; + plugins.corePlugins.concat(plugins.otherPlugins).forEach(pluginData => { + const index = allCategories.findIndex( + chip => chip.name === pluginData.category, + ); + if (index === -1) { + allCategories.push({ + name: pluginData.category, + isSelected: false, + }); + } + }); -

- Open source plugins that you can add to your Backstage deployment. - Learn how to build a plugin. -

+ const [categories, setCategories] = useState(allCategories); + const [selectedCategories, setSelectedCategories] = useState([]); + const [showCoreFeaturesHeader, setShowCoreFeaturesHeader] = useState(true); + const [showOtherPluginsHeader, setShowOtherPluginsHeader] = useState(true); + + const handleChipClick = (categoryName: string) => { + console.log(categoryName); + const category = categories.find( + category => category.name === categoryName, + ); + const isSelected = category?.isSelected || false; + + let newSelectedCategories = selectedCategories; + + if (isSelected) { + newSelectedCategories = selectedCategories.filter( + c => c !== categoryName, + ); + } else { + newSelectedCategories.push(categoryName); + } + + setSelectedCategories(newSelectedCategories); + + const newCategories = categories.map(category => { + if (category.name === categoryName) { + return { ...category, isSelected: !isSelected }; + } + return category; + }); + + setCategories(newCategories); + + if (!newSelectedCategories.includes('Core Feature')) { + setShowCoreFeaturesHeader(false); + } else { + setShowCoreFeaturesHeader(true); + } + + if ( + newSelectedCategories.length === 1 && + newSelectedCategories[0] === 'Core Feature' + ) { + setShowOtherPluginsHeader(false); + } else { + setShowOtherPluginsHeader(true); + } + + if (newSelectedCategories.length === 0) { + setShowOtherPluginsHeader(true); + setShowCoreFeaturesHeader(true); + } + }; + + return ( + +
+
+
+

Plugin Marketplace

+ +

+ Open source plugins that you can add to your Backstage deployment. + Learn how to build a plugin. +

+
+ + + Add to Marketplace +
- - Add to Marketplace - +
+ + + + {showCoreFeaturesHeader &&

Core Features

} + +
+ {plugins.corePlugins + .filter( + pluginData => + !selectedCategories.length || + selectedCategories.includes(pluginData.category), + ) + .map(pluginData => ( + + ))} +
+ + {showOtherPluginsHeader &&

All Plugins

} + +
+ {plugins.otherPlugins + .filter( + pluginData => + !selectedCategories.length || + selectedCategories.includes(pluginData.category), + ) + .map(pluginData => ( + + ))} +
- -
- -

Core Features

- -
- {plugins.corePlugins.map(pluginData => ( - - ))} -
- -

All Plugins

- -
- {plugins.otherPlugins.map(pluginData => ( - - ))} -
-
- -); + + ); +}; export default Plugins; diff --git a/microsite/src/pages/plugins/plugins.module.scss b/microsite/src/pages/plugins/plugins.module.scss index bb08c2fd33..2f928fcbf0 100644 --- a/microsite/src/pages/plugins/plugins.module.scss +++ b/microsite/src/pages/plugins/plugins.module.scss @@ -28,10 +28,43 @@ :global(.pluginsContainer) { gap: 1rem; display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + grid-template-columns: repeat(auto-fit, minmax(250px, 300px)); } :global(.fit-content) { width: fit-content; } + + :global(.dropdown) { + float: right; + } + + :global(.button--info) { + background-color: transparent; + border-color: var(--ifm-color-primary); + color: var(--ifm-color-primary); + min-width: 250px; + } + + :global(label.dropdown__item) { + display: flex; + align-items: center; + cursor: pointer; + margin-top: 5px; + + &:hover { + background-color: var(--ifm-color-primary); + color: black; + } + } + + :global(.dropdown__label) { + font-size: 15px; + cursor: pointer; + } + + :global(.dropdown__checkbox) { + margin-right: 10px; + cursor: pointer; + } } diff --git a/microsite/src/util/types.ts b/microsite/src/util/types.ts new file mode 100644 index 0000000000..fba7c0ba46 --- /dev/null +++ b/microsite/src/util/types.ts @@ -0,0 +1,4 @@ +export type ChipCategory = { + name: string; + isSelected: boolean; +};