1
0
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:
Matthias Kretschmann 2019-09-13 13:22:02 +02:00
parent 921e8fe764
commit ca6029b034
Signed by: m
GPG Key ID: 606EEEF3C479A91F
10 changed files with 170 additions and 157 deletions

View File

@ -22,7 +22,7 @@
composes: inputWrap; composes: inputWrap;
.input { .input {
padding-left: $spacer * 1.5; padding-left: $spacer;
} }
svg { svg {

View 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'))
})
})

View File

@ -1,5 +1,4 @@
import React from 'react' import React from 'react'
import shortid from 'shortid'
import Button from '../../components/atoms/Button' import Button from '../../components/atoms/Button'
import styles from './FilterItem.module.scss' import styles from './FilterItem.module.scss'
@ -17,10 +16,7 @@ export default function FilterItem({
filterByLicense(license: string): void filterByLicense(license: string): void
}) { }) {
return ( return (
<li <li className={isActive ? styles.active : styles.item}>
key={shortid.generate()}
className={isActive ? styles.active : styles.item}
>
<Button <Button
link link
className={styles.option} className={styles.option}

View File

@ -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;
}

View File

@ -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>
))}
</>
)
}

View File

@ -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;
}

View File

@ -3,13 +3,13 @@ import { render } from '@testing-library/react'
import { User } from '../../context' import { User } from '../../context'
import { userMockConnected } from '../../../__mocks__/user-mock' import { userMockConnected } from '../../../__mocks__/user-mock'
import searchMock from '../../../__fixtures__/search.json' import searchMock from '../../../__fixtures__/search.json'
import Filters from './Filters' import Sidebar from './Sidebar'
describe('Filters', () => { describe('Sidebar', () => {
it('renders without crashing', () => { it('renders without crashing', () => {
const { container } = render( const { container } = render(
<User.Provider value={userMockConnected}> <User.Provider value={userMockConnected}>
<Filters <Sidebar
category="Architecture" category="Architecture"
license="Public" license="Public"
results={searchMock.results} results={searchMock.results}

View File

@ -1,48 +1,94 @@
import React from 'react' import React from 'react'
import Input from '../../components/atoms/Form/Input' import shortid from 'shortid'
import Filters from './Filters' import { DDO } from '@oceanprotocol/squid'
import data from '../../data/form-publish.json'
import FilterItem from './FilterItem'
import styles from './Sidebar.module.scss' 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({ export default function Sidebar({
search,
inputChange,
category, category,
license, license,
results, results,
filterByCategory, filterByCategory,
filterByLicense filterByLicense
}: { }: {
search: string
inputChange: any
category: string category: string
license: string license: string
results: any[] results: any[]
filterByCategory(category: string): void filterByCategory(category: string): void
filterByLicense(license: string): void filterByLicense(license: string): void
}) { }) {
const { filterCategories, filterLicenses } = getFilterMetadata(results)
const filters = [
{ label: labelCategories, items: filterCategories },
{ label: labelLicense, items: filterLicenses }
]
return ( return (
<aside className={styles.sidebar}> <aside className={styles.sidebar}>
<Input {filters.map(filter => (
type="search" <div key={shortid.generate()} className={styles.filter}>
name="search" <h3 className={styles.filterTitle}>{filter.label}</h3>
label="Search" <ul className={styles.filter}>
placeholder="e.g. shapes of plants" {filter.items &&
value={search} filter.items
onChange={inputChange} .sort((a: string, b: string) =>
// group={ a.localeCompare(b)
// <Button primary onClick={search}> ) // sort alphabetically
// Search .map((option: string) => {
// </Button> const isActive =
// } category === option ||
/> license === option
<Filters return (
category={category} <FilterItem
license={license} key={shortid.generate()}
results={results} isActive={isActive}
filterByCategory={filterByCategory} filter={filter}
filterByLicense={filterByLicense} filterByCategory={filterByCategory}
/> filterByLicense={filterByLicense}
option={option}
/>
)
})}
</ul>
</div>
))}
</aside> </aside>
) )
} }

View File

@ -4,8 +4,9 @@
display: grid; display: grid;
grid-gap: $spacer * 2; grid-gap: $spacer * 2;
grid-template-columns: 1fr; grid-template-columns: 1fr;
margin-top: $spacer * 2;
@media (min-width: $break-point--medium) { @media (min-width: $break-point--medium) {
grid-template-columns: 1fr 3fr; grid-template-columns: 3fr 1fr;
} }
} }

View File

@ -6,6 +6,7 @@ import Spinner from '../../components/atoms/Spinner'
import Route from '../../components/templates/Route' import Route from '../../components/templates/Route'
import { User } from '../../context' import { User } from '../../context'
import Content from '../../components/atoms/Content' import Content from '../../components/atoms/Content'
import Input from '../../components/atoms/Form/Input'
import withTracker from '../../hoc/withTracker' import withTracker from '../../hoc/withTracker'
import Sidebar from './Sidebar' import Sidebar from './Sidebar'
import Results from './Results' import Results from './Results'
@ -206,19 +207,24 @@ class Search extends PureComponent<SearchProps, SearchState> {
} = this.state } = this.state
return ( 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> <Content wide>
<div className={styles.content}> <div className={styles.content}>
<Sidebar
search={search}
inputChange={this.inputChange}
category={category}
results={results}
license={license}
filterByCategory={this.filterByCategory}
filterByLicense={this.filterByLicense}
/>
<div> <div>
{isLoading ? ( {isLoading ? (
<Spinner message="Searching..." /> <Spinner message="Searching..." />
@ -235,6 +241,14 @@ class Search extends PureComponent<SearchProps, SearchState> {
/> />
)} )}
</div> </div>
<Sidebar
category={category}
license={license}
results={results}
filterByCategory={this.filterByCategory}
filterByLicense={this.filterByLicense}
/>
</div> </div>
</Content> </Content>
</Route> </Route>