mirror of
https://github.com/oceanprotocol/commons.git
synced 2023-03-15 18:03:00 +01:00
search page component reorder
This commit is contained in:
parent
921e8fe764
commit
ca6029b034
@ -22,7 +22,7 @@
|
||||
composes: inputWrap;
|
||||
|
||||
.input {
|
||||
padding-left: $spacer * 1.5;
|
||||
padding-left: $spacer;
|
||||
}
|
||||
|
||||
svg {
|
||||
|
51
client/src/routes/Search/FilterItem.test.tsx
Normal file
51
client/src/routes/Search/FilterItem.test.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
import React from 'react'
|
||||
import { render, fireEvent } from '@testing-library/react'
|
||||
import FilterItem from './FilterItem'
|
||||
|
||||
describe('FilterItem', () => {
|
||||
const filterByCategory = jest.fn()
|
||||
const filterByLicense = jest.fn()
|
||||
|
||||
it('renders without crashing', () => {
|
||||
const { container } = render(
|
||||
<FilterItem
|
||||
isActive={false}
|
||||
filter={{ label: 'Category' }}
|
||||
filterByCategory={filterByCategory}
|
||||
filterByLicense={filterByLicense}
|
||||
option="Hello"
|
||||
/>
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('filterByCategory can be called', () => {
|
||||
const { getByText, getByTitle } = render(
|
||||
<FilterItem
|
||||
isActive
|
||||
filter={{ label: 'Category' }}
|
||||
filterByCategory={filterByCategory}
|
||||
filterByLicense={filterByLicense}
|
||||
option="Hello"
|
||||
/>
|
||||
)
|
||||
fireEvent.click(getByText(/Hello/))
|
||||
expect(filterByCategory).toHaveBeenCalled()
|
||||
fireEvent.click(getByTitle('Clear'))
|
||||
})
|
||||
|
||||
it('filterByLicense can be called', () => {
|
||||
const { getByText, getByTitle } = render(
|
||||
<FilterItem
|
||||
isActive
|
||||
filter={{ label: 'License' }}
|
||||
filterByCategory={filterByCategory}
|
||||
filterByLicense={filterByLicense}
|
||||
option="Hello"
|
||||
/>
|
||||
)
|
||||
fireEvent.click(getByText(/Hello/))
|
||||
expect(filterByLicense).toHaveBeenCalled()
|
||||
fireEvent.click(getByTitle('Clear'))
|
||||
})
|
||||
})
|
@ -1,5 +1,4 @@
|
||||
import React from 'react'
|
||||
import shortid from 'shortid'
|
||||
import Button from '../../components/atoms/Button'
|
||||
import styles from './FilterItem.module.scss'
|
||||
|
||||
@ -17,10 +16,7 @@ export default function FilterItem({
|
||||
filterByLicense(license: string): void
|
||||
}) {
|
||||
return (
|
||||
<li
|
||||
key={shortid.generate()}
|
||||
className={isActive ? styles.active : styles.item}
|
||||
>
|
||||
<li className={isActive ? styles.active : styles.item}>
|
||||
<Button
|
||||
link
|
||||
className={styles.option}
|
||||
|
@ -1,16 +0,0 @@
|
||||
@import '../../styles/variables';
|
||||
|
||||
.filter {
|
||||
ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.filterTitle {
|
||||
font-size: $font-size-base;
|
||||
color: $brand-grey-light;
|
||||
margin-top: 0;
|
||||
border-bottom: 1px solid $brand-grey-lighter;
|
||||
padding-bottom: $spacer / 4;
|
||||
margin-bottom: $spacer / 4;
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
import React from 'react'
|
||||
import shortid from 'shortid'
|
||||
import styles from './Filters.module.scss'
|
||||
import data from '../../data/form-publish.json'
|
||||
import FilterItem from './FilterItem'
|
||||
import { DDO } from '@oceanprotocol/squid'
|
||||
|
||||
const { steps } = data
|
||||
|
||||
const labelCategories =
|
||||
steps &&
|
||||
steps[1].fields &&
|
||||
steps[1].fields.categories &&
|
||||
steps[1].fields.categories.label
|
||||
|
||||
const labelLicense =
|
||||
steps &&
|
||||
steps[2].fields &&
|
||||
steps[2].fields.license &&
|
||||
steps[2].fields.license.label
|
||||
|
||||
function getFilterMetadata(results: any[]) {
|
||||
let filterCategories: string[] = []
|
||||
let filterLicenses: string[] = []
|
||||
|
||||
results.map((asset: DDO) => {
|
||||
if (!asset.findServiceByType) return null
|
||||
const { metadata } = asset.findServiceByType('Metadata')
|
||||
const { categories, license } = metadata.base
|
||||
categories && filterCategories.push(categories[0])
|
||||
license && filterLicenses.push(license)
|
||||
return null
|
||||
})
|
||||
|
||||
// remove duplicates
|
||||
filterCategories = Array.from(new Set(filterCategories))
|
||||
filterLicenses = Array.from(new Set(filterLicenses))
|
||||
|
||||
return { filterCategories, filterLicenses }
|
||||
}
|
||||
|
||||
export default function Filters({
|
||||
category,
|
||||
license,
|
||||
results,
|
||||
filterByCategory,
|
||||
filterByLicense
|
||||
}: {
|
||||
category: string
|
||||
license: string
|
||||
results: any[]
|
||||
filterByCategory(category: string): void
|
||||
filterByLicense(license: string): void
|
||||
}) {
|
||||
const { filterCategories, filterLicenses } = getFilterMetadata(results)
|
||||
|
||||
const filters = [
|
||||
{ label: labelCategories, items: filterCategories },
|
||||
{ label: labelLicense, items: filterLicenses }
|
||||
]
|
||||
|
||||
return (
|
||||
<>
|
||||
{filters.map(filter => (
|
||||
<div key={shortid.generate()} className={styles.filter}>
|
||||
<h3 className={styles.filterTitle}>{filter.label}</h3>
|
||||
<ul className={styles.filter}>
|
||||
{filter.items &&
|
||||
filter.items
|
||||
.sort((a: string, b: string) =>
|
||||
a.localeCompare(b)
|
||||
) // sort alphabetically
|
||||
.map((option: string) => {
|
||||
const isActive =
|
||||
category === option ||
|
||||
license === option
|
||||
|
||||
return (
|
||||
<FilterItem
|
||||
key={shortid.generate()}
|
||||
isActive={isActive}
|
||||
filter={filter}
|
||||
filterByCategory={filterByCategory}
|
||||
filterByLicense={filterByLicense}
|
||||
option={option}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
@ -11,3 +11,18 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filter {
|
||||
ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.filterTitle {
|
||||
font-size: $font-size-base;
|
||||
color: $brand-grey-light;
|
||||
margin-top: 0;
|
||||
border-bottom: 1px solid $brand-grey-lighter;
|
||||
padding-bottom: $spacer / 4;
|
||||
margin-bottom: $spacer / 4;
|
||||
}
|
||||
|
@ -3,13 +3,13 @@ import { render } from '@testing-library/react'
|
||||
import { User } from '../../context'
|
||||
import { userMockConnected } from '../../../__mocks__/user-mock'
|
||||
import searchMock from '../../../__fixtures__/search.json'
|
||||
import Filters from './Filters'
|
||||
import Sidebar from './Sidebar'
|
||||
|
||||
describe('Filters', () => {
|
||||
describe('Sidebar', () => {
|
||||
it('renders without crashing', () => {
|
||||
const { container } = render(
|
||||
<User.Provider value={userMockConnected}>
|
||||
<Filters
|
||||
<Sidebar
|
||||
category="Architecture"
|
||||
license="Public"
|
||||
results={searchMock.results}
|
@ -1,48 +1,94 @@
|
||||
import React from 'react'
|
||||
import Input from '../../components/atoms/Form/Input'
|
||||
import Filters from './Filters'
|
||||
import shortid from 'shortid'
|
||||
import { DDO } from '@oceanprotocol/squid'
|
||||
import data from '../../data/form-publish.json'
|
||||
import FilterItem from './FilterItem'
|
||||
import styles from './Sidebar.module.scss'
|
||||
|
||||
const { steps } = data
|
||||
|
||||
const labelCategories =
|
||||
steps &&
|
||||
steps[1].fields &&
|
||||
steps[1].fields.categories &&
|
||||
steps[1].fields.categories.label
|
||||
|
||||
const labelLicense =
|
||||
steps &&
|
||||
steps[2].fields &&
|
||||
steps[2].fields.license &&
|
||||
steps[2].fields.license.label
|
||||
|
||||
function getFilterMetadata(results: any[]) {
|
||||
let filterCategories: string[] = []
|
||||
let filterLicenses: string[] = []
|
||||
|
||||
results.map((asset: DDO) => {
|
||||
if (!asset.findServiceByType) return null
|
||||
const { metadata } = asset.findServiceByType('Metadata')
|
||||
const { categories, license } = metadata.base
|
||||
categories && filterCategories.push(categories[0])
|
||||
license && filterLicenses.push(license)
|
||||
return null
|
||||
})
|
||||
|
||||
// remove duplicates
|
||||
filterCategories = Array.from(new Set(filterCategories))
|
||||
filterLicenses = Array.from(new Set(filterLicenses))
|
||||
|
||||
return { filterCategories, filterLicenses }
|
||||
}
|
||||
|
||||
export default function Sidebar({
|
||||
search,
|
||||
inputChange,
|
||||
category,
|
||||
license,
|
||||
results,
|
||||
filterByCategory,
|
||||
filterByLicense
|
||||
}: {
|
||||
search: string
|
||||
inputChange: any
|
||||
category: string
|
||||
license: string
|
||||
results: any[]
|
||||
filterByCategory(category: string): void
|
||||
filterByLicense(license: string): void
|
||||
}) {
|
||||
const { filterCategories, filterLicenses } = getFilterMetadata(results)
|
||||
|
||||
const filters = [
|
||||
{ label: labelCategories, items: filterCategories },
|
||||
{ label: labelLicense, items: filterLicenses }
|
||||
]
|
||||
|
||||
return (
|
||||
<aside className={styles.sidebar}>
|
||||
<Input
|
||||
type="search"
|
||||
name="search"
|
||||
label="Search"
|
||||
placeholder="e.g. shapes of plants"
|
||||
value={search}
|
||||
onChange={inputChange}
|
||||
// group={
|
||||
// <Button primary onClick={search}>
|
||||
// Search
|
||||
// </Button>
|
||||
// }
|
||||
/>
|
||||
{filters.map(filter => (
|
||||
<div key={shortid.generate()} className={styles.filter}>
|
||||
<h3 className={styles.filterTitle}>{filter.label}</h3>
|
||||
<ul className={styles.filter}>
|
||||
{filter.items &&
|
||||
filter.items
|
||||
.sort((a: string, b: string) =>
|
||||
a.localeCompare(b)
|
||||
) // sort alphabetically
|
||||
.map((option: string) => {
|
||||
const isActive =
|
||||
category === option ||
|
||||
license === option
|
||||
|
||||
<Filters
|
||||
category={category}
|
||||
license={license}
|
||||
results={results}
|
||||
filterByCategory={filterByCategory}
|
||||
filterByLicense={filterByLicense}
|
||||
/>
|
||||
return (
|
||||
<FilterItem
|
||||
key={shortid.generate()}
|
||||
isActive={isActive}
|
||||
filter={filter}
|
||||
filterByCategory={filterByCategory}
|
||||
filterByLicense={filterByLicense}
|
||||
option={option}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
</aside>
|
||||
)
|
||||
}
|
||||
|
@ -4,8 +4,9 @@
|
||||
display: grid;
|
||||
grid-gap: $spacer * 2;
|
||||
grid-template-columns: 1fr;
|
||||
margin-top: $spacer * 2;
|
||||
|
||||
@media (min-width: $break-point--medium) {
|
||||
grid-template-columns: 1fr 3fr;
|
||||
grid-template-columns: 3fr 1fr;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import Spinner from '../../components/atoms/Spinner'
|
||||
import Route from '../../components/templates/Route'
|
||||
import { User } from '../../context'
|
||||
import Content from '../../components/atoms/Content'
|
||||
import Input from '../../components/atoms/Form/Input'
|
||||
import withTracker from '../../hoc/withTracker'
|
||||
import Sidebar from './Sidebar'
|
||||
import Results from './Results'
|
||||
@ -206,19 +207,24 @@ class Search extends PureComponent<SearchProps, SearchState> {
|
||||
} = this.state
|
||||
|
||||
return (
|
||||
<Route title="Search" wide>
|
||||
<Route title="Search">
|
||||
<Content>
|
||||
<Input
|
||||
type="search"
|
||||
name="search"
|
||||
label=""
|
||||
placeholder="e.g. shapes of plants"
|
||||
value={search}
|
||||
onChange={this.inputChange}
|
||||
// group={
|
||||
// <Button primary onClick={this.executeSearch}>
|
||||
// Search
|
||||
// </Button>
|
||||
// }
|
||||
/>
|
||||
</Content>
|
||||
<Content wide>
|
||||
<div className={styles.content}>
|
||||
<Sidebar
|
||||
search={search}
|
||||
inputChange={this.inputChange}
|
||||
category={category}
|
||||
results={results}
|
||||
license={license}
|
||||
filterByCategory={this.filterByCategory}
|
||||
filterByLicense={this.filterByLicense}
|
||||
/>
|
||||
|
||||
<div>
|
||||
{isLoading ? (
|
||||
<Spinner message="Searching..." />
|
||||
@ -235,6 +241,14 @@ class Search extends PureComponent<SearchProps, SearchState> {
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Sidebar
|
||||
category={category}
|
||||
license={license}
|
||||
results={results}
|
||||
filterByCategory={this.filterByCategory}
|
||||
filterByLicense={this.filterByLicense}
|
||||
/>
|
||||
</div>
|
||||
</Content>
|
||||
</Route>
|
||||
|
Loading…
Reference in New Issue
Block a user