Marketplace: Adding filters and a collapsible panel show/hide

This commit is contained in:
vinodkiran
2024-02-05 18:09:46 -05:00
parent 8990b78e10
commit 842d70bf0d
55 changed files with 199 additions and 60 deletions
@@ -10,6 +10,8 @@ import TableRow from '@mui/material/TableRow'
import Paper from '@mui/material/Paper'
import Chip from '@mui/material/Chip'
import { Button, Typography } from '@mui/material'
import langchainPNG from 'assets/images/langchain.png'
import llamaIndexPNG from 'assets/images/llamaindex.png'
const StyledTableCell = styled(TableCell)(({ theme }) => ({
[`&.${tableCellClasses.head}`]: {
@@ -31,7 +33,7 @@ const StyledTableRow = styled(TableRow)(({ theme }) => ({
}
}))
export const MarketplaceTable = ({ data, images, filterFunction, filterByBadge, filterByType }) => {
export const MarketplaceTable = ({ data, filterFunction, filterByBadge, filterByType, filterByFramework }) => {
const navigate = useNavigate()
const openTemplate = (selectedTemplate) => {
if (selectedTemplate.flowData) {
@@ -61,10 +63,13 @@ export const MarketplaceTable = ({ data, images, filterFunction, filterByBadge,
<Table sx={{ minWidth: 650 }} size='small' aria-label='a dense table'>
<TableHead>
<TableRow sx={{ marginTop: '10', backgroundColor: 'primary' }}>
<StyledTableCell component='th' scope='row' style={{ width: '5%' }} key='0'>
{''}
</StyledTableCell>
<StyledTableCell component='th' scope='row' style={{ width: '15%' }} key='0'>
Name
</StyledTableCell>
<StyledTableCell component='th' scope='row' style={{ width: '10%' }} key='1'>
<StyledTableCell component='th' scope='row' style={{ width: '5%' }} key='1'>
Type
</StyledTableCell>
<StyledTableCell style={{ width: '35%' }} key='2'>
@@ -83,9 +88,20 @@ export const MarketplaceTable = ({ data, images, filterFunction, filterByBadge,
.filter(filterByBadge)
.filter(filterByType)
.filter(filterFunction)
.filter(filterByFramework)
.map((row, index) => (
<StyledTableRow key={index}>
<TableCell key='0'>
<Typography>
{row.framework === 'Langchain' && (
<img src={langchainPNG} alt='langchain' style={{ width: 30, height: 30 }} />
)}
{row.framework === 'LlamaIndex' && (
<img src={llamaIndexPNG} alt='llamaIndex' style={{ width: 30, height: 30 }} />
)}
</Typography>
</TableCell>
<TableCell key='1'>
<Typography
sx={{ fontSize: '1.2rem', fontWeight: 500, overflowWrap: 'break-word', whiteSpace: 'pre-line' }}
>
@@ -94,15 +110,15 @@ export const MarketplaceTable = ({ data, images, filterFunction, filterByBadge,
</Button>
</Typography>
</TableCell>
<TableCell key='1'>
<TableCell key='2'>
<Typography>{row.type}</Typography>
</TableCell>
<TableCell key='1'>
<TableCell key='3'>
<Typography sx={{ overflowWrap: 'break-word', whiteSpace: 'pre-line' }}>
{row.description || ''}
</Typography>
</TableCell>
<TableCell key='2'>
<TableCell key='4'>
<div
style={{
display: 'flex',
@@ -125,7 +141,7 @@ export const MarketplaceTable = ({ data, images, filterFunction, filterByBadge,
))}
</div>
</TableCell>
<TableCell key='3'>
<TableCell key='5'>
<Typography>
{row.badge &&
row.badge
@@ -152,8 +168,8 @@ export const MarketplaceTable = ({ data, images, filterFunction, filterByBadge,
MarketplaceTable.propTypes = {
data: PropTypes.array,
images: PropTypes.object,
filterFunction: PropTypes.func,
filterByBadge: PropTypes.func,
filterByType: PropTypes.func
filterByType: PropTypes.func,
filterByFramework: PropTypes.func
}
+119 -51
View File
@@ -19,10 +19,11 @@ import {
Select,
OutlinedInput,
Checkbox,
ListItemText
ListItemText,
Button
} from '@mui/material'
import { useTheme } from '@mui/material/styles'
import { IconLayoutGrid, IconList, IconSearch } from '@tabler/icons'
import { IconChevronsDown, IconChevronsUp, IconLayoutGrid, IconList, IconSearch } from '@tabler/icons'
// project imports
import MainCard from 'ui-component/cards/MainCard'
@@ -69,6 +70,7 @@ const ITEM_HEIGHT = 48
const ITEM_PADDING_TOP = 8
const badges = ['POPULAR', 'NEW']
const types = ['Chatflow', 'Tool']
const framework = ['Langchain', 'LlamaIndex']
const MenuProps = {
PaperProps: {
style: {
@@ -98,7 +100,8 @@ const Marketplace = () => {
const [badgeFilter, setBadgeFilter] = useState([])
const [typeFilter, setTypeFilter] = useState([])
const [frameworkFilter, setFrameworkFilter] = useState([])
const [open, setOpen] = useState(false)
const handleBadgeFilterChange = (event) => {
const {
target: { value }
@@ -117,6 +120,15 @@ const Marketplace = () => {
typeof value === 'string' ? value.split(',') : value
)
}
const handleFrameworkFilterChange = (event) => {
const {
target: { value }
} = event
setFrameworkFilter(
// On autofill we get a stringified value.
typeof value === 'string' ? value.split(',') : value
)
}
const handleViewChange = (event, nextView) => {
localStorage.setItem('mpDisplayStyle', nextView)
@@ -143,6 +155,10 @@ const Marketplace = () => {
return typeFilter.length > 0 ? typeFilter.includes(data.type) : true
}
function filterByFramework(data) {
return frameworkFilter.length > 0 ? frameworkFilter.includes(data.framework) : true
}
const onUseTemplate = (selectedTool) => {
const dialogProp = {
title: 'Add New Tool',
@@ -224,9 +240,11 @@ const Marketplace = () => {
<h1>Marketplace</h1>
<TextField
size='small'
id='search-filter-textbox'
sx={{ display: { xs: 'none', sm: 'block' }, ml: 3 }}
variant='outlined'
placeholder='Search name or description'
fullWidth='true'
placeholder='Search name or description or node name'
onChange={onSearchChange}
InputProps={{
startAdornment: (
@@ -236,52 +254,14 @@ const Marketplace = () => {
)
}}
/>
<FormControl sx={{ m: 1, width: 300 }}>
<InputLabel size='small' id='type-badge'>
Type
</InputLabel>
<Select
size='small'
labelId='type-badge-checkbox-label'
id='type-badge-checkbox'
multiple
value={typeFilter}
onChange={handleTypeFilterChange}
input={<OutlinedInput label='Badge' />}
renderValue={(selected) => selected.join(', ')}
MenuProps={MenuProps}
>
{types.map((name) => (
<MenuItem key={name} value={name}>
<Checkbox checked={typeFilter.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
<FormControl sx={{ m: 1, width: 300 }}>
<InputLabel size='small' id='filter-badge'>
Tag
</InputLabel>
<Select
labelId='filter-badge-label'
id='filter-badge-checkbox'
size='small'
multiple
value={badgeFilter}
onChange={handleBadgeFilterChange}
input={<OutlinedInput label='Badge' />}
renderValue={(selected) => selected.join(', ')}
MenuProps={MenuProps}
>
{badges.map((name) => (
<MenuItem key={name} value={name}>
<Checkbox checked={badgeFilter.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
<Button
sx={{ width: '220px', ml: 3, mr: 5 }}
variant='outlined'
onClick={() => setOpen(!open)}
startIcon={open ? <IconChevronsUp /> : <IconChevronsDown />}
>
{open ? 'Hide Filters' : 'Show Filters'}
</Button>
<Box sx={{ flexGrow: 1 }} />
<ButtonGroup sx={{ maxHeight: 40 }} disableElevation variant='contained' aria-label='outlined primary button group'>
<ButtonGroup disableElevation variant='contained' aria-label='outlined primary button group'>
@@ -313,6 +293,93 @@ const Marketplace = () => {
</ButtonGroup>
</Toolbar>
</Box>
{open && (
<Box sx={{ flexGrow: 1, mb: 2 }}>
<Toolbar
disableGutters={true}
style={{
margin: 1,
padding: 1,
paddingBottom: 10,
display: 'flex',
justifyContent: 'flex-start',
width: '100%',
borderBottom: '1px solid'
}}
>
<FormControl sx={{ m: 1, width: 250 }}>
<InputLabel size='small' id='filter-badge-label'>
Tag
</InputLabel>
<Select
labelId='filter-badge-label'
id='filter-badge-checkbox'
size='small'
multiple
value={badgeFilter}
onChange={handleBadgeFilterChange}
input={<OutlinedInput label='Badge' />}
renderValue={(selected) => selected.join(', ')}
MenuProps={MenuProps}
>
{badges.map((name) => (
<MenuItem key={name} value={name}>
<Checkbox checked={badgeFilter.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
<FormControl sx={{ m: 1, width: 250 }}>
<InputLabel size='small' id='type-badge-label'>
Type
</InputLabel>
<Select
size='small'
labelId='type-badge-label'
id='type-badge-checkbox'
multiple
value={typeFilter}
onChange={handleTypeFilterChange}
input={<OutlinedInput label='Badge' />}
renderValue={(selected) => selected.join(', ')}
MenuProps={MenuProps}
>
{types.map((name) => (
<MenuItem key={name} value={name}>
<Checkbox checked={typeFilter.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
<FormControl sx={{ m: 1, width: 250 }}>
<InputLabel size='small' id='type-fw-label'>
Framework
</InputLabel>
<Select
size='small'
labelId='type-fw-label'
id='type-fw-checkbox'
multiple
value={frameworkFilter}
onChange={handleFrameworkFilterChange}
input={<OutlinedInput label='Badge' />}
renderValue={(selected) => selected.join(', ')}
MenuProps={MenuProps}
>
{framework.map((name) => (
<MenuItem key={name} value={name}>
<Checkbox checked={frameworkFilter.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
</Toolbar>
</Box>
)}
{!isLoading && (!view || view === 'card') && getAllTemplatesMarketplacesApi.data && (
<>
<Grid container spacing={gridSpacing}>
@@ -320,6 +387,7 @@ const Marketplace = () => {
.filter(filterByBadge)
.filter(filterByType)
.filter(filterFlows)
.filter(filterByFramework)
.map((data, index) => (
<Grid key={index} item lg={3} md={4} sm={6} xs={12}>
{data.badge && (
@@ -351,10 +419,10 @@ const Marketplace = () => {
<MarketplaceTable
sx={{ mt: 20 }}
data={getAllTemplatesMarketplacesApi.data}
images={images}
filterFunction={filterFlows}
filterByType={filterByType}
filterByBadge={filterByBadge}
filterByFramework={filterByFramework}
/>
)}