Skip to content

Commit

Permalink
Merge pull request #421 from deltaDAO/feat/update-filters
Browse files Browse the repository at this point in the history
feat: update filters
  • Loading branch information
oceanByte authored Oct 4, 2023
2 parents 83b65d8 + 4db6f37 commit 90c5d7b
Show file tree
Hide file tree
Showing 27 changed files with 922 additions and 568 deletions.
46 changes: 46 additions & 0 deletions filters.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module.exports = {
filters: [
{
id: 'filterSet',
label: 'Categories',
type: 'filterList',
options: [
{
label: 'automotive',
value: 'automotive'
},
{
label: 'manufacturing',
value: 'manufacturing'
},
{
label: 'text analysis',
value: 'textAnalysis'
},
{
label: 'finance',
value: 'finance'
}
]
}
],
filterSets: {
automotive: [
'charging',
'ev',
'gx4m',
'mobility',
'moveid',
'parking',
'traffic'
],
manufacturing: [
'euprogigant',
'industry40',
'manufacturing',
'predictive-maintenance'
],
textAnalysis: ['library', 'ocr', 'text-analysis'],
finance: ['graphql']
}
}
66 changes: 66 additions & 0 deletions src/@context/Filter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React, {
createContext,
useContext,
ReactElement,
ReactNode,
useState
} from 'react'
import {
SortDirectionOptions,
SortTermOptions
} from '../../src/@types/aquarius/SearchQuery'

export interface Filters {
[key: string]: string[]
}

export interface Sort {
sort: SortTermOptions
sortOrder: SortDirectionOptions
}

interface FilterValue {
filters: Filters
setFilters: (filters: Filters) => void
ignorePurgatory: boolean
setIgnorePurgatory: (value: boolean) => void
sort: Sort
setSort: (sort: Sort) => void
}

const FilterContext = createContext({} as FilterValue)

function FilterProvider({ children }: { children: ReactNode }): ReactElement {
const [filters, setFilters] = useState<Filters>({
accessType: [],
serviceType: [],
filterSet: []
})
const [ignorePurgatory, setIgnorePurgatory] = useState<boolean>(true)
const [sort, setSort] = useState<Sort>({
sort: SortTermOptions.Created,
sortOrder: SortDirectionOptions.Descending
})

return (
<FilterContext.Provider
value={
{
filters,
setFilters,
ignorePurgatory,
setIgnorePurgatory,
sort,
setSort
} as FilterValue
}
>
{children}
</FilterContext.Provider>
)
}

// Helper hook to access the provider values
const useFilter = (): FilterValue => useContext(FilterContext)

export { FilterProvider, useFilter }
12 changes: 12 additions & 0 deletions src/@hooks/useDebounce.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useEffect, useCallback } from 'react'

const useDebounce = (effect, dependencies: any[], delay: number) => {
const callback = useCallback(effect, dependencies)

useEffect(() => {
const timeout = setTimeout(callback, delay)
return () => clearTimeout(timeout)
}, [callback, delay])
}

export default useDebounce
5 changes: 5 additions & 0 deletions src/@types/aquarius/SearchQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export enum SortTermOptions {
// Only export/import works for that, so this file is NOT .d.ts file ending
// and gets imported in components.

export enum FilterOptions {
AccessType = 'accessType',
ServiceType = 'serviceType'
}

export enum FilterByTypeOptions {
Data = 'dataset',
Algorithm = 'algorithm'
Expand Down
11 changes: 9 additions & 2 deletions src/@utils/aquarius/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import {
SortDirectionOptions,
SortTermOptions
} from '../../@types/aquarius/SearchQuery'
import { escapeEsReservedCharacters, getFilterTerm, generateBaseQuery } from '.'
import {
escapeEsReservedCharacters,
getFilterTerm,
generateBaseQuery,
getWhitelistShould
} from '.'

const defaultBaseQueryReturn = {
from: 0,
Expand All @@ -20,7 +25,9 @@ const defaultBaseQueryReturn = {
]
}
}
]
],
should: [...getWhitelistShould()],
...(getWhitelistShould().length > 0 ? { minimum_should_match: 1 } : [])
}
},
size: 1000
Expand Down
58 changes: 43 additions & 15 deletions src/@utils/aquarius/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
import { transformAssetToAssetSelection } from '../assetConvertor'
import addressConfig from '../../../address.config'
import { isValidDid } from '@utils/ddo'
import { Filters } from '@context/Filter'
import { filterSets } from '@components/Search/Filter'

export interface UserSales {
id: string
Expand Down Expand Up @@ -46,8 +48,37 @@ export function getFilterTerm(
}
}

export function getWhitelistShould(): // eslint-disable-next-line camelcase
{ should: FilterTerm[]; minimum_should_match: 1 } | undefined {
export function parseFilters(
filtersList: Filters,
filterSets: { [key: string]: string[] }
): FilterTerm[] {
const filterQueryPath = {
accessType: 'services.type',
serviceType: 'metadata.type',
filterSet: 'metadata.tags.keyword'
}

const filterTerms = Object.keys(filtersList)?.map((key) => {
if (key === 'filterSet') {
const tags = filtersList[key].reduce(
(acc, set) => [...acc, ...filterSets[set]],
[]
)
const uniqueTags = [...new Set(tags)]
return uniqueTags.length > 0
? getFilterTerm(filterQueryPath[key], uniqueTags)
: undefined
}
if (filtersList[key].length > 0)
return getFilterTerm(filterQueryPath[key], filtersList[key])

return undefined
})

return filterTerms.filter((term) => term !== undefined)
}

export function getWhitelistShould(): FilterTerm[] {
const { whitelists } = addressConfig

const whitelistFilterTerms = Object.entries(whitelists)
Expand All @@ -57,12 +88,7 @@ export function getWhitelistShould(): // eslint-disable-next-line camelcase
)
.reduce((prev, cur) => prev.concat(cur), [])

return whitelistFilterTerms.length > 0
? {
should: whitelistFilterTerms,
minimum_should_match: 1
}
: undefined
return whitelistFilterTerms.length > 0 ? whitelistFilterTerms : []
}

export function getDynamicPricingMustNot(): // eslint-disable-next-line camelcase
Expand Down Expand Up @@ -102,7 +128,7 @@ export function generateBaseQuery(
}
}
],
...getWhitelistShould()
should: [...getWhitelistShould()]
}
}
} as SearchQuery
Expand All @@ -117,6 +143,11 @@ export function generateBaseQuery(
baseQueryParams.sortOptions.sortDirection ||
SortDirectionOptions.Descending
}

if (generatedQuery.query?.bool?.should?.length > 0) {
generatedQuery.query.bool.minimum_should_match = 1
}

return generatedQuery
}

Expand Down Expand Up @@ -289,19 +320,16 @@ export async function getPublishedAssets(
cancelToken: CancelToken,
ignorePurgatory = false,
ignoreState = false,
page?: number,
type?: string,
accesType?: string
filtersList?: Filters,
page?: number
): Promise<PagedAssets> {
if (!accountId) return

const filters: FilterTerm[] = []

filters.push(getFilterTerm('nft.state', [0, 4, 5]))
filters.push(getFilterTerm('nft.owner', accountId.toLowerCase()))
accesType !== undefined &&
filters.push(getFilterTerm('services.type', accesType))
type !== undefined && filters.push(getFilterTerm('metadata.type', type))
parseFilters(filtersList, filterSets).forEach((term) => filters.push(term))

const baseQueryParams = {
chainIds,
Expand Down
62 changes: 62 additions & 0 deletions src/components/@shared/Accordion/index.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
.title,
.compactTitle {
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
margin-bottom: 0;
color: var(--font-color-title);
}

.title > span:first-child,
.compactTitle > span:first-child {
margin-right: calc(var(--spacer) / 4);
}

.compactTitle {
font-size: var(--font-size-h5);
}

.badge {
margin: 0;
background-color: var(--menu-border-color);
color: var(--menu-network-badge-font-color);
font-size: var(--font-size-base);
vertical-align: middle;
}

.toggle {
margin-left: calc(var(--spacer) / 4);
transform: none !important;
}

.toggle svg {
display: inline-block;
width: var(--font-size-base);
height: var(--font-size-base);
fill: var(--font-color-title);
vertical-align: middle;
transition: 0.2s ease-out;
}

.open .toggle svg {
transform: rotate(180deg);
}

.actions .content {
max-height: 0;
visibility: hidden;
overflow: hidden;
transition: 0.3s;
}

.open .content {
max-height: 35rem;
visibility: visible;
overflow-y: scroll;
transition: 0.3s max-height;
}

.open .compactContent {
max-height: 15rem;
}
56 changes: 56 additions & 0 deletions src/components/@shared/Accordion/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React, { ReactElement, ReactNode, useState } from 'react'
import Button from '@shared/atoms/Button'
import styles from './index.module.css'
import Caret from '@images/caret.svg'
import classNames from 'classnames/bind'
import Badge from '@shared/atoms/Badge'

const cx = classNames.bind(styles)

export default function Accordion({
title,
defaultExpanded = false,
badgeNumber,
compact,
action,
children
}: {
title: string
defaultExpanded?: boolean
badgeNumber?: number
compact?: boolean
action?: ReactNode
children: ReactNode
}): ReactElement {
const [open, setOpen] = useState(!!defaultExpanded)

async function handleClick() {
setOpen(!open)
}

return (
<div className={cx({ actions: true, open })}>
<h3
className={compact ? styles.compactTitle : styles.title}
onClick={handleClick}
>
<span>{title}</span>
{badgeNumber > 0 && (
<Badge label={badgeNumber} className={styles.badge} />
)}
<Button
style="text"
size="small"
onClick={handleClick}
className={styles.toggle}
>
<Caret />
</Button>
</h3>
{action}
<div className={cx({ content: true, compactContent: compact })}>
{children}
</div>
</div>
)
}
Loading

0 comments on commit 90c5d7b

Please sign in to comment.