mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
add sort filter features to search (#322)
* sort and filter working added ui element for filter * added UI for filter and sort * made sort and filter work with the new UI * filter and sort inline style * updated styling and linters * added sort direction * apply sort and filter when starting a new search and sort order style update * fixed sort by price * change sort order selector change direction when click on a sort option instead of clicking on the arrow that shows actual sort direction * added default sort to owner and tag search * refactor getSearchQuery method * refactor sort methods * fixed lint errors * updated styling for sort and filter components * fixed lint * apply dynamic filter when sorting by liquidity * interaction & alignment styling * style tweaks, legacy search layout styles removal * refactor sort component and fixed browsing all datasets also aded default sort params when browsing all data sets * fixed lint issues Co-authored-by: Matthias Kretschmann <m@kretschmann.io>
This commit is contained in:
parent
0cad79ae97
commit
83dca873f8
@ -63,7 +63,7 @@ export default function Publisher({
|
|||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Link
|
<Link
|
||||||
to={`/search/?owner=${account}`}
|
to={`/search/?owner=${account}&sort=created&sortOrder=desc`}
|
||||||
title="Show all data sets created by this account."
|
title="Show all data sets created by this account."
|
||||||
>
|
>
|
||||||
{name}
|
{name}
|
||||||
|
@ -15,7 +15,11 @@ const Tag = ({ tag, noLinks }: { tag: string; noLinks?: boolean }) => {
|
|||||||
return noLinks ? (
|
return noLinks ? (
|
||||||
<span className={styles.tag}>{tag}</span>
|
<span className={styles.tag}>{tag}</span>
|
||||||
) : (
|
) : (
|
||||||
<Link to={`/search?tags=${tag}`} className={styles.tag} title={tag}>
|
<Link
|
||||||
|
to={`/search?tags=${tag}&sort=created&sortOrder=desc`}
|
||||||
|
className={styles.tag}
|
||||||
|
title={tag}
|
||||||
|
>
|
||||||
{tag}
|
{tag}
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
|
@ -4,6 +4,7 @@ import styles from './SearchBar.module.css'
|
|||||||
import Button from '../atoms/Button'
|
import Button from '../atoms/Button'
|
||||||
import Input from '../atoms/Input'
|
import Input from '../atoms/Input'
|
||||||
import InputGroup from '../atoms/Input/InputGroup'
|
import InputGroup from '../atoms/Input/InputGroup'
|
||||||
|
import { addExistingParamsToUrl } from '../templates/Search/utils'
|
||||||
|
|
||||||
export default function SearchBar({
|
export default function SearchBar({
|
||||||
placeholder,
|
placeholder,
|
||||||
@ -23,10 +24,11 @@ export default function SearchBar({
|
|||||||
setValue(e.target.value)
|
setValue(e.target.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
function startSearch(e: FormEvent<HTMLButtonElement>) {
|
async function startSearch(e: FormEvent<HTMLButtonElement>) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (value === '') return
|
if (value === '') return
|
||||||
navigate(`/search?text=${value}`)
|
const url = await addExistingParamsToUrl(location, 'text')
|
||||||
|
navigate(`${url}&text=${value}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -41,7 +43,11 @@ export default function SearchBar({
|
|||||||
required
|
required
|
||||||
size={size}
|
size={size}
|
||||||
/>
|
/>
|
||||||
<Button onClick={(e: FormEvent<HTMLButtonElement>) => startSearch(e)}>
|
<Button
|
||||||
|
onClick={async (e: FormEvent<HTMLButtonElement>) =>
|
||||||
|
await startSearch(e)
|
||||||
|
}
|
||||||
|
>
|
||||||
Search
|
Search
|
||||||
</Button>
|
</Button>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
@ -112,7 +112,7 @@ export default function HomePage(): ReactElement {
|
|||||||
title="New Data Sets"
|
title="New Data Sets"
|
||||||
query={queryLatest}
|
query={queryLatest}
|
||||||
action={
|
action={
|
||||||
<Button style="text" to="/search">
|
<Button style="text" to="/search?sort=created&sortOrder=desc">
|
||||||
All data sets →
|
All data sets →
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
|
33
src/components/templates/Search/filterPrice.module.css
Normal file
33
src/components/templates/Search/filterPrice.module.css
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/* .filterList {
|
||||||
|
display: inline-flex;
|
||||||
|
float: left;
|
||||||
|
} */
|
||||||
|
|
||||||
|
.filter,
|
||||||
|
button.filter,
|
||||||
|
.filter:hover,
|
||||||
|
.filter:active,
|
||||||
|
.filter:focus {
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
text-transform: uppercase;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
margin-right: calc(var(--spacer) / 6);
|
||||||
|
color: var(--color-secondary);
|
||||||
|
background: var(--background-body);
|
||||||
|
|
||||||
|
/* the only thing not possible to overwrite button style="text" with more specifity of selectors, so sledgehammer */
|
||||||
|
padding: calc(var(--spacer) / 5) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter:hover,
|
||||||
|
.filter:focus {
|
||||||
|
color: var(--font-color-text);
|
||||||
|
background: inherit;
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter.selected {
|
||||||
|
color: var(--background-body);
|
||||||
|
background: var(--font-color-text);
|
||||||
|
border-color: var(--background-body);
|
||||||
|
}
|
57
src/components/templates/Search/filterPrice.tsx
Normal file
57
src/components/templates/Search/filterPrice.tsx
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import React, { ReactElement } from 'react'
|
||||||
|
import { useNavigate } from '@reach/router'
|
||||||
|
import styles from './filterPrice.module.css'
|
||||||
|
import classNames from 'classnames/bind'
|
||||||
|
import { addExistingParamsToUrl, FilterByPriceOptions } from './utils'
|
||||||
|
import Button from '../../atoms/Button'
|
||||||
|
|
||||||
|
const cx = classNames.bind(styles)
|
||||||
|
|
||||||
|
const filterItems = [
|
||||||
|
{ display: 'all', value: undefined },
|
||||||
|
{ display: 'fixed price', value: FilterByPriceOptions.Fixed },
|
||||||
|
{ display: 'dynamic price', value: FilterByPriceOptions.Dynamic }
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function FilterPrice({
|
||||||
|
priceType,
|
||||||
|
setPriceType
|
||||||
|
}: {
|
||||||
|
priceType: string
|
||||||
|
setPriceType: React.Dispatch<React.SetStateAction<string>>
|
||||||
|
}): ReactElement {
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
async function applyFilter(filterBy: string) {
|
||||||
|
let urlLocation = await addExistingParamsToUrl(location, 'priceType')
|
||||||
|
if (filterBy) {
|
||||||
|
urlLocation = `${urlLocation}&priceType=${filterBy}`
|
||||||
|
}
|
||||||
|
setPriceType(filterBy)
|
||||||
|
navigate(urlLocation)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{filterItems.map((e, index) => {
|
||||||
|
const filter = cx({
|
||||||
|
[styles.selected]: e.value === priceType,
|
||||||
|
[styles.filter]: true
|
||||||
|
})
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
style="text"
|
||||||
|
key={index}
|
||||||
|
className={filter}
|
||||||
|
onClick={async () => {
|
||||||
|
await applyFilter(e.value)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{e.display}
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -1,21 +1,19 @@
|
|||||||
.grid {
|
.row {
|
||||||
display: grid;
|
display: inline-flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin-bottom: calc(var(--spacer) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 55rem) {
|
.row > div {
|
||||||
.grid {
|
margin-bottom: calc(var(--spacer) / 2);
|
||||||
grid-column-gap: calc(var(--spacer) * 3);
|
}
|
||||||
/* grid-template-columns: minmax(0, 3fr) 1fr; */
|
|
||||||
grid-template-areas:
|
|
||||||
'search'
|
|
||||||
'results';
|
|
||||||
}
|
|
||||||
|
|
||||||
.search {
|
@media (min-width: 40rem) {
|
||||||
grid-area: search;
|
.row {
|
||||||
}
|
flex-direction: row;
|
||||||
|
|
||||||
.results {
|
|
||||||
grid-area: results;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,9 @@ import SearchBar from '../../molecules/SearchBar'
|
|||||||
import AssetQueryList from '../../organisms/AssetQueryList'
|
import AssetQueryList from '../../organisms/AssetQueryList'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import queryString from 'query-string'
|
import queryString from 'query-string'
|
||||||
import { getResults } from './utils'
|
import PriceFilter from './filterPrice'
|
||||||
|
import Sort from './sort'
|
||||||
|
import { getResults, addExistingParamsToUrl } from './utils'
|
||||||
import Loader from '../../atoms/Loader'
|
import Loader from '../../atoms/Loader'
|
||||||
import { useOcean } from '@oceanprotocol/react'
|
import { useOcean } from '@oceanprotocol/react'
|
||||||
|
|
||||||
@ -17,9 +19,14 @@ export default function SearchPage({
|
|||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { config } = useOcean()
|
const { config } = useOcean()
|
||||||
const parsed = queryString.parse(location.search)
|
const parsed = queryString.parse(location.search)
|
||||||
const { text, owner, tags, page } = parsed
|
const { text, owner, tags, page, sort, sortOrder, priceType } = parsed
|
||||||
const [queryResult, setQueryResult] = useState<QueryResult>()
|
const [queryResult, setQueryResult] = useState<QueryResult>()
|
||||||
const [loading, setLoading] = useState<boolean>()
|
const [loading, setLoading] = useState<boolean>()
|
||||||
|
const [price, setPriceType] = useState<string>(priceType as string)
|
||||||
|
const [sortType, setSortType] = useState<string>(sort as string)
|
||||||
|
const [sortDirection, setSortDirection] = useState<string>(
|
||||||
|
sortOrder as string
|
||||||
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!config?.metadataCacheUri) return
|
if (!config?.metadataCacheUri) return
|
||||||
@ -33,18 +40,37 @@ export default function SearchPage({
|
|||||||
setLoading(false)
|
setLoading(false)
|
||||||
}
|
}
|
||||||
initSearch()
|
initSearch()
|
||||||
}, [text, owner, tags, page, config.metadataCacheUri])
|
}, [
|
||||||
|
text,
|
||||||
|
owner,
|
||||||
|
tags,
|
||||||
|
page,
|
||||||
|
sort,
|
||||||
|
priceType,
|
||||||
|
sortOrder,
|
||||||
|
config.metadataCacheUri
|
||||||
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={styles.grid}>
|
<>
|
||||||
<div className={styles.search}>
|
<div className={styles.search}>
|
||||||
{(text || owner) && (
|
{(text || owner) && (
|
||||||
<SearchBar initialValue={(text || owner) as string} />
|
<SearchBar initialValue={(text || owner) as string} />
|
||||||
)}
|
)}
|
||||||
|
<div className={styles.row}>
|
||||||
|
<PriceFilter priceType={price} setPriceType={setPriceType} />
|
||||||
|
<Sort
|
||||||
|
sortType={sortType}
|
||||||
|
sortDirection={sortDirection}
|
||||||
|
setSortType={setSortType}
|
||||||
|
setSortDirection={setSortDirection}
|
||||||
|
setPriceType={setPriceType}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.results}>
|
<div className={styles.results}>
|
||||||
{loading ? <Loader /> : <AssetQueryList queryResult={queryResult} />}
|
{loading ? <Loader /> : <AssetQueryList queryResult={queryResult} />}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
48
src/components/templates/Search/sort.module.css
Normal file
48
src/components/templates/Search/sort.module.css
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
.sortList {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
background: var(--background-body);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sortLabel {
|
||||||
|
composes: label from '../../atoms/Input/Label.module.css';
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-left: calc(var(--spacer) / 2);
|
||||||
|
margin-right: calc(var(--spacer) / 1.5);
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--color-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sorted {
|
||||||
|
display: flex;
|
||||||
|
padding: calc(var(--spacer) / 6) calc(var(--spacer) / 2);
|
||||||
|
margin-right: calc(var(--spacer) / 4);
|
||||||
|
color: var(--color-secondary);
|
||||||
|
text-transform: capitalize;
|
||||||
|
border-radius: 0;
|
||||||
|
font-weight: var(--font-weight-base);
|
||||||
|
background: var(--background-body);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sorted:hover,
|
||||||
|
.sorted:focus,
|
||||||
|
.sorted.selected {
|
||||||
|
color: var(--font-color-text);
|
||||||
|
background: inherit;
|
||||||
|
transform: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.direction {
|
||||||
|
display: flex;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: inherit;
|
||||||
|
font-size: 0.75em;
|
||||||
|
outline: none;
|
||||||
|
margin-left: calc(var(--spacer) / 8);
|
||||||
|
margin-top: calc(var(--spacer) / 14);
|
||||||
|
}
|
94
src/components/templates/Search/sort.tsx
Normal file
94
src/components/templates/Search/sort.tsx
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import React, { ReactElement } from 'react'
|
||||||
|
import { useNavigate } from '@reach/router'
|
||||||
|
import {
|
||||||
|
addExistingParamsToUrl,
|
||||||
|
SortTermOptions,
|
||||||
|
SortValueOptions,
|
||||||
|
FilterByPriceOptions
|
||||||
|
} from './utils'
|
||||||
|
import Button from '../../atoms/Button'
|
||||||
|
import styles from './sort.module.css'
|
||||||
|
import classNames from 'classnames/bind'
|
||||||
|
|
||||||
|
const cx = classNames.bind(styles)
|
||||||
|
|
||||||
|
const sortItems = [
|
||||||
|
{ display: 'Published', value: SortTermOptions.Created },
|
||||||
|
{ display: 'Liquidity', value: SortTermOptions.Liquidity },
|
||||||
|
{ display: 'Price', value: SortTermOptions.Price }
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function Sort({
|
||||||
|
sortType,
|
||||||
|
setSortType,
|
||||||
|
sortDirection,
|
||||||
|
setSortDirection,
|
||||||
|
setPriceType
|
||||||
|
}: {
|
||||||
|
sortType: string
|
||||||
|
setSortType: React.Dispatch<React.SetStateAction<string>>
|
||||||
|
sortDirection: string
|
||||||
|
setSortDirection: React.Dispatch<React.SetStateAction<string>>
|
||||||
|
setPriceType: React.Dispatch<React.SetStateAction<string>>
|
||||||
|
}): ReactElement {
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const directionArrow = String.fromCharCode(
|
||||||
|
sortDirection === SortValueOptions.Ascending ? 9650 : 9660
|
||||||
|
)
|
||||||
|
async function sortResults(sortBy?: string, direction?: string) {
|
||||||
|
let urlLocation: string
|
||||||
|
if (sortBy) {
|
||||||
|
urlLocation = await addExistingParamsToUrl(location, 'sort', 'priceType')
|
||||||
|
urlLocation = `${urlLocation}&sort=${sortBy}`
|
||||||
|
if (sortBy === SortTermOptions.Liquidity) {
|
||||||
|
urlLocation = `${urlLocation}&priceType=${FilterByPriceOptions.Dynamic}`
|
||||||
|
setPriceType(FilterByPriceOptions.Dynamic)
|
||||||
|
} else {
|
||||||
|
setPriceType(undefined)
|
||||||
|
}
|
||||||
|
setSortType(sortBy)
|
||||||
|
} else if (direction) {
|
||||||
|
urlLocation = await addExistingParamsToUrl(location, 'sortOrder')
|
||||||
|
urlLocation = `${urlLocation}&sortOrder=${direction}`
|
||||||
|
setSortDirection(direction)
|
||||||
|
}
|
||||||
|
navigate(urlLocation)
|
||||||
|
}
|
||||||
|
function handleSortButtonClick(value: string) {
|
||||||
|
if (value === sortType) {
|
||||||
|
if (sortDirection === SortValueOptions.Descending) {
|
||||||
|
sortResults(null, SortValueOptions.Ascending)
|
||||||
|
} else {
|
||||||
|
sortResults(null, SortValueOptions.Descending)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sortResults(value, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className={styles.sortList}>
|
||||||
|
<label className={styles.sortLabel}>Sort</label>
|
||||||
|
{sortItems.map((e, index) => {
|
||||||
|
const sorted = cx({
|
||||||
|
[styles.selected]: e.value === sortType,
|
||||||
|
[styles.sorted]: true
|
||||||
|
})
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
key={index}
|
||||||
|
className={sorted}
|
||||||
|
size="small"
|
||||||
|
onClick={() => {
|
||||||
|
handleSortButtonClick(e.value)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{e.display}
|
||||||
|
{e.value === sortType ? (
|
||||||
|
<span className={styles.direction}>{directionArrow}</span>
|
||||||
|
) : null}
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -3,6 +3,52 @@ import {
|
|||||||
QueryResult
|
QueryResult
|
||||||
} from '@oceanprotocol/lib/dist/node/metadatacache/MetadataCache'
|
} from '@oceanprotocol/lib/dist/node/metadatacache/MetadataCache'
|
||||||
import { MetadataCache, Logger } from '@oceanprotocol/lib'
|
import { MetadataCache, Logger } from '@oceanprotocol/lib'
|
||||||
|
import queryString from 'query-string'
|
||||||
|
|
||||||
|
export const SortTermOptions = {
|
||||||
|
Liquidity: 'liquidity',
|
||||||
|
Price: 'price',
|
||||||
|
Created: 'created'
|
||||||
|
} as const
|
||||||
|
type SortTermOptions = typeof SortTermOptions[keyof typeof SortTermOptions]
|
||||||
|
|
||||||
|
export const SortElasticTerm = {
|
||||||
|
Liquidity: 'price.ocean',
|
||||||
|
Price: 'price.value',
|
||||||
|
Created: 'created'
|
||||||
|
} as const
|
||||||
|
type SortElasticTerm = typeof SortElasticTerm[keyof typeof SortElasticTerm]
|
||||||
|
|
||||||
|
export const SortValueOptions = {
|
||||||
|
Ascending: 'asc',
|
||||||
|
Descending: 'desc'
|
||||||
|
} as const
|
||||||
|
type SortValueOptions = typeof SortValueOptions[keyof typeof SortValueOptions]
|
||||||
|
|
||||||
|
export const FilterByPriceOptions = {
|
||||||
|
Fixed: 'exchange',
|
||||||
|
Dynamic: 'pool'
|
||||||
|
} as const
|
||||||
|
type FilterByPriceOptions = typeof FilterByPriceOptions[keyof typeof FilterByPriceOptions]
|
||||||
|
|
||||||
|
function addPriceFilterToQuerry(sortTerm: string, priceFilter: string): string {
|
||||||
|
sortTerm = priceFilter
|
||||||
|
? sortTerm === ''
|
||||||
|
? `price.type:${priceFilter}`
|
||||||
|
: `${sortTerm} AND price.type:${priceFilter}`
|
||||||
|
: sortTerm
|
||||||
|
return sortTerm
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSortType(sortParam: string): string {
|
||||||
|
const sortTerm =
|
||||||
|
sortParam === SortTermOptions.Liquidity
|
||||||
|
? SortElasticTerm.Liquidity
|
||||||
|
: sortParam === SortTermOptions.Price
|
||||||
|
? SortElasticTerm.Price
|
||||||
|
: SortTermOptions.Created
|
||||||
|
return sortTerm
|
||||||
|
}
|
||||||
|
|
||||||
export function getSearchQuery(
|
export function getSearchQuery(
|
||||||
text?: string,
|
text?: string,
|
||||||
@ -10,9 +56,14 @@ export function getSearchQuery(
|
|||||||
tags?: string,
|
tags?: string,
|
||||||
categories?: string,
|
categories?: string,
|
||||||
page?: string,
|
page?: string,
|
||||||
offset?: string
|
offset?: string,
|
||||||
|
sort?: string,
|
||||||
|
sortOrder?: string,
|
||||||
|
priceType?: string
|
||||||
): SearchQuery {
|
): SearchQuery {
|
||||||
const searchTerm = owner
|
const sortTerm = getSortType(sort)
|
||||||
|
const sortValue = sortOrder === SortValueOptions.Ascending ? 1 : -1
|
||||||
|
let searchTerm = owner
|
||||||
? `(publicKey.owner:${owner})`
|
? `(publicKey.owner:${owner})`
|
||||||
: tags
|
: tags
|
||||||
? // eslint-disable-next-line no-useless-escape
|
? // eslint-disable-next-line no-useless-escape
|
||||||
@ -21,6 +72,7 @@ export function getSearchQuery(
|
|||||||
? // eslint-disable-next-line no-useless-escape
|
? // eslint-disable-next-line no-useless-escape
|
||||||
`(service.attributes.additionalInformation.categories:\"${categories}\")`
|
`(service.attributes.additionalInformation.categories:\"${categories}\")`
|
||||||
: text || ''
|
: text || ''
|
||||||
|
searchTerm = addPriceFilterToQuerry(searchTerm, priceType)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
page: Number(page) || 1,
|
page: Number(page) || 1,
|
||||||
@ -35,7 +87,7 @@ export function getSearchQuery(
|
|||||||
// ...(categories && { categories: [categories] })
|
// ...(categories && { categories: [categories] })
|
||||||
},
|
},
|
||||||
sort: {
|
sort: {
|
||||||
created: -1
|
[sortTerm]: sortValue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Something in ocean.js is weird when using 'tags: [tag]'
|
// Something in ocean.js is weird when using 'tags: [tag]'
|
||||||
@ -57,11 +109,23 @@ export async function getResults(
|
|||||||
categories?: string
|
categories?: string
|
||||||
page?: string
|
page?: string
|
||||||
offset?: string
|
offset?: string
|
||||||
|
sort?: string
|
||||||
|
sortOrder?: string
|
||||||
|
priceType?: string
|
||||||
},
|
},
|
||||||
metadataCacheUri: string
|
metadataCacheUri: string
|
||||||
): Promise<QueryResult> {
|
): Promise<QueryResult> {
|
||||||
const { text, owner, tags, page, offset, categories } = params
|
const {
|
||||||
|
text,
|
||||||
|
owner,
|
||||||
|
tags,
|
||||||
|
page,
|
||||||
|
offset,
|
||||||
|
categories,
|
||||||
|
sort,
|
||||||
|
sortOrder,
|
||||||
|
priceType
|
||||||
|
} = params
|
||||||
const metadataCache = new MetadataCache(metadataCacheUri, Logger)
|
const metadataCache = new MetadataCache(metadataCacheUri, Logger)
|
||||||
const searchQuery = getSearchQuery(
|
const searchQuery = getSearchQuery(
|
||||||
text,
|
text,
|
||||||
@ -69,9 +133,40 @@ export async function getResults(
|
|||||||
tags,
|
tags,
|
||||||
categories,
|
categories,
|
||||||
page,
|
page,
|
||||||
offset
|
offset,
|
||||||
|
sort,
|
||||||
|
sortOrder,
|
||||||
|
priceType
|
||||||
)
|
)
|
||||||
const queryResult = await metadataCache.queryMetadata(searchQuery)
|
const queryResult = await metadataCache.queryMetadata(searchQuery)
|
||||||
|
|
||||||
return queryResult
|
return queryResult
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function addExistingParamsToUrl(
|
||||||
|
location: Location,
|
||||||
|
excludedParam: string,
|
||||||
|
secondExcludedParam?: string
|
||||||
|
): Promise<string> {
|
||||||
|
const parsed = queryString.parse(location.search)
|
||||||
|
let urlLocation = '/search?'
|
||||||
|
if (Object.keys(parsed).length > 0) {
|
||||||
|
for (const querryParam in parsed) {
|
||||||
|
if (
|
||||||
|
querryParam !== excludedParam &&
|
||||||
|
querryParam !== secondExcludedParam
|
||||||
|
) {
|
||||||
|
if (querryParam === 'page' && excludedParam === 'text') {
|
||||||
|
Logger.log('remove page when starting a new search')
|
||||||
|
} else {
|
||||||
|
const value = parsed[querryParam]
|
||||||
|
urlLocation = `${urlLocation}${querryParam}=${value}&`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
urlLocation = `${urlLocation}sort=${SortTermOptions.Created}&sortOrder=${SortValueOptions.Descending}&`
|
||||||
|
}
|
||||||
|
urlLocation = urlLocation.slice(0, -1)
|
||||||
|
return urlLocation
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user