From 6cd4177c6415712dd9a22a959fbf09b8a496882c Mon Sep 17 00:00:00 2001 From: "antonio.bergas" Date: Fri, 28 Apr 2023 14:51:57 +0200 Subject: [PATCH 1/5] =?UTF-8?q?=E2=9C=A8=20feat(pluginsFilter):=20added=20?= =?UTF-8?q?dropdown=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; +}; From c630c0d7ebd1e4ca5ce777d5e992b2bfc3892d5d Mon Sep 17 00:00:00 2001 From: Antonio Bergas Date: Wed, 17 May 2023 21:29:35 +0200 Subject: [PATCH 2/5] refactor(microsite/src/pages/plugins/index.tsx): Refactor of newSelectedCategories Co-authored-by: Ben Lambert Signed-off-by: Antonio Bergas --- microsite/src/pages/plugins/index.tsx | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/microsite/src/pages/plugins/index.tsx b/microsite/src/pages/plugins/index.tsx index 2349e391fa..02f7854110 100644 --- a/microsite/src/pages/plugins/index.tsx +++ b/microsite/src/pages/plugins/index.tsx @@ -56,15 +56,9 @@ const Plugins = () => { ); const isSelected = category?.isSelected || false; - let newSelectedCategories = selectedCategories; - - if (isSelected) { - newSelectedCategories = selectedCategories.filter( + const newSelectedCategories = isSelected ? selectedCategories.filter( c => c !== categoryName, - ); - } else { - newSelectedCategories.push(categoryName); - } + ) : selectedCategories.push(categoryName); setSelectedCategories(newSelectedCategories); From dfd0dd0475b9186e2a76e2a5b701f8ac681910ec Mon Sep 17 00:00:00 2001 From: "antonio.bergas" Date: Wed, 17 May 2023 23:19:37 +0200 Subject: [PATCH 3/5] =?UTF-8?q?=E2=9C=A8=20feat(pluginsFilter):=20added=20?= =?UTF-8?q?dropdown=20filter=20for=20plugins=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: antonio.bergas --- microsite/src/pages/plugins/index.tsx | 41 ++++++++++++--------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/microsite/src/pages/plugins/index.tsx b/microsite/src/pages/plugins/index.tsx index 02f7854110..6b2ebe22a1 100644 --- a/microsite/src/pages/plugins/index.tsx +++ b/microsite/src/pages/plugins/index.tsx @@ -31,34 +31,29 @@ plugins.corePlugins.sort((a, b) => a.order - b.order); plugins.otherPlugins.sort((a, b) => a.order - b.order); 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, - }); - } - }); - - const [categories, setCategories] = useState(allCategories); - const [selectedCategories, setSelectedCategories] = useState([]); + const allCategoriesSet = new Set( + [...plugins.corePlugins, ...plugins.otherPlugins].map( + ({ category }) => category, + ), + ); + const allCategoriesArray = Array.from(allCategoriesSet).map(category => ({ + name: category, + isSelected: false, + })); + const [categories, setCategories] = + useState(allCategoriesArray); + 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; + const isSelected = + categories.find(category => category.name === categoryName)?.isSelected || + false; - const newSelectedCategories = isSelected ? selectedCategories.filter( - c => c !== categoryName, - ) : selectedCategories.push(categoryName); + const newSelectedCategories = isSelected + ? selectedCategories.filter(c => c !== categoryName) + : [...selectedCategories, categoryName]; setSelectedCategories(newSelectedCategories); From c8c711acac47e89c4cc2c1a1408318468e4ead06 Mon Sep 17 00:00:00 2001 From: "antonio.bergas" Date: Thu, 18 May 2023 11:01:58 +0200 Subject: [PATCH 4/5] =?UTF-8?q?=E2=9C=A8=20feat(pluginsFilter):=20fixed=20?= =?UTF-8?q?style=20issues?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: antonio.bergas --- microsite/src/pages/plugins/index.tsx | 11 ++++++----- microsite/src/pages/plugins/plugins.module.scss | 13 +++++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/microsite/src/pages/plugins/index.tsx b/microsite/src/pages/plugins/index.tsx index 6b2ebe22a1..6b1116712a 100644 --- a/microsite/src/pages/plugins/index.tsx +++ b/microsite/src/pages/plugins/index.tsx @@ -111,11 +111,12 @@ const Plugins = () => {
- - +
+ +
{showCoreFeaturesHeader &&

Core Features

} diff --git a/microsite/src/pages/plugins/plugins.module.scss b/microsite/src/pages/plugins/plugins.module.scss index 2f928fcbf0..3babf0959c 100644 --- a/microsite/src/pages/plugins/plugins.module.scss +++ b/microsite/src/pages/plugins/plugins.module.scss @@ -31,12 +31,25 @@ grid-template-columns: repeat(auto-fit, minmax(250px, 300px)); } + @media (max-width: 768px) { + :global(.pluginsContainer) { + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + } + } + :global(.fit-content) { width: fit-content; } + :global(.pluginsFilterBox) { + width: 100%; + margin-bottom: 1rem; + height: 1rem; + } + :global(.dropdown) { float: right; + margin-bottom: 1rem; } :global(.button--info) { From e64ebe6106e58fad510960fb1c71aed7b5818a14 Mon Sep 17 00:00:00 2001 From: "antonio.bergas" Date: Thu, 18 May 2023 11:28:11 +0200 Subject: [PATCH 5/5] =?UTF-8?q?=E2=9C=A8=20feat(pluginsFilter):=20refineme?= =?UTF-8?q?nt=20of=20hide=20&&=20dropdown=20behaviours?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: antonio.bergas --- .../pluginsFilter/pluginsFilter.tsx | 2 +- microsite/src/pages/plugins/index.tsx | 80 +++++++++++-------- .../src/pages/plugins/plugins.module.scss | 4 + 3 files changed, 51 insertions(+), 35 deletions(-) diff --git a/microsite/src/components/pluginsFilter/pluginsFilter.tsx b/microsite/src/components/pluginsFilter/pluginsFilter.tsx index 19b80b9f14..25c8a5ff52 100644 --- a/microsite/src/components/pluginsFilter/pluginsFilter.tsx +++ b/microsite/src/components/pluginsFilter/pluginsFilter.tsx @@ -15,7 +15,7 @@ const PluginsFilter = ({ categories, handleChipClick }: Props) => {
    {categories.map(chip => { return ( -
  • +
  • handleChipClick(chip.name)}>
    { const [categories, setCategories] = useState(allCategoriesArray); const [selectedCategories, setSelectedCategories] = useState([]); - const [showCoreFeaturesHeader, setShowCoreFeaturesHeader] = useState(true); - const [showOtherPluginsHeader, setShowOtherPluginsHeader] = useState(true); + const [showCoreFeatures, setShowCoreFeatures] = useState(true); + const [showOtherPlugins, setShowOtherPlugins] = useState(true); const handleChipClick = (categoryName: string) => { const isSelected = @@ -67,23 +67,23 @@ const Plugins = () => { setCategories(newCategories); if (!newSelectedCategories.includes('Core Feature')) { - setShowCoreFeaturesHeader(false); + setShowCoreFeatures(false); } else { - setShowCoreFeaturesHeader(true); + setShowCoreFeatures(true); } if ( newSelectedCategories.length === 1 && newSelectedCategories[0] === 'Core Feature' ) { - setShowOtherPluginsHeader(false); + setShowOtherPlugins(false); } else { - setShowOtherPluginsHeader(true); + setShowOtherPlugins(true); } if (newSelectedCategories.length === 0) { - setShowOtherPluginsHeader(true); - setShowCoreFeaturesHeader(true); + setShowOtherPlugins(true); + setShowCoreFeatures(true); } }; @@ -118,33 +118,45 @@ const Plugins = () => { />
    - {showCoreFeaturesHeader &&

    Core Features

    } + {showCoreFeatures && ( +
    +

    Core Features

    +
    + {plugins.corePlugins + .filter( + pluginData => + !selectedCategories.length || + selectedCategories.includes(pluginData.category), + ) + .map(pluginData => ( + + ))} +
    +
    + )} -
    - {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 => ( - - ))} -
    + {showOtherPlugins && ( +
    +

    All Plugins

    +
    + {plugins.otherPlugins + .filter( + pluginData => + !selectedCategories.length || + selectedCategories.includes(pluginData.category), + ) + .map(pluginData => ( + + ))} +
    +
    + )}
); diff --git a/microsite/src/pages/plugins/plugins.module.scss b/microsite/src/pages/plugins/plugins.module.scss index 3babf0959c..d5ea5de6e7 100644 --- a/microsite/src/pages/plugins/plugins.module.scss +++ b/microsite/src/pages/plugins/plugins.module.scss @@ -37,6 +37,10 @@ } } + :global(.hidePluginsHeader) { + display: none; + } + :global(.fit-content) { width: fit-content; }