1
0
mirror of https://github.com/oceanprotocol/commons.git synced 2023-03-15 18:03:00 +01:00
This commit is contained in:
Jernej Pregelj 2019-02-06 16:23:45 +01:00
commit 7d4261cec1
14 changed files with 2205 additions and 480 deletions

25
.eslintrc Normal file
View File

@ -0,0 +1,25 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json"
},
"extends": [
"oceanprotocol",
"oceanprotocol/react",
"plugin:prettier/recommended",
"prettier/react",
"prettier/standard",
"plugin:@typescript-eslint/recommended"
],
"plugins": ["@typescript-eslint", "prettier"],
"rules": {
"@typescript-eslint/explicit-function-return-type": 0,
"@typescript-eslint/member-delimiter-style": [
"error",
{ "multiline": { "delimiter": "none" } }
]
},
"env": {
"jest": true
}
}

2085
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@
"format:css": "prettier-stylelint --write --quiet 'src/**/*.{css,scss}'", "format:css": "prettier-stylelint --write --quiet 'src/**/*.{css,scss}'",
"format": "npm run format:js && npm run format:css", "format": "npm run format:js && npm run format:css",
"lint:css": "stylelint './src/**/*.{css,scss}'", "lint:css": "stylelint './src/**/*.{css,scss}'",
"lint:js": "tslint -c tslint.json 'src/**/*.{ts,tsx}'", "lint:js": "eslint --ignore-path .gitignore --ignore-path .prettierignore --ext .ts,.tsx .",
"lint": "npm run lint:js && npm run lint:css" "lint": "npm run lint:js && npm run lint:css"
}, },
"dependencies": { "dependencies": {
@ -32,16 +32,19 @@
"@types/react-dom": "16.0.11", "@types/react-dom": "16.0.11",
"@types/react-router-dom": "^4.3.1", "@types/react-router-dom": "^4.3.1",
"@types/web3": "^1.0.18", "@types/web3": "^1.0.18",
"@typescript-eslint/eslint-plugin": "^1.2.0",
"@typescript-eslint/parser": "^1.2.0",
"eslint-config-oceanprotocol": "^1.3.0",
"eslint-config-prettier": "^3.3.0",
"eslint-plugin-prettier": "^3.0.0",
"node-sass": "^4.11.0", "node-sass": "^4.11.0",
"prettier": "^1.16.2", "prettier": "^1.16.2",
"prettier-stylelint": "^0.4.2", "prettier-stylelint": "^0.4.2",
"react-scripts": "2.1.3", "react-scripts": "2.1.3",
"stylelint": "^9.10.1",
"stylelint-config-bigchaindb": "^1.2.1", "stylelint-config-bigchaindb": "^1.2.1",
"stylelint-config-css-modules": "^1.3.0", "stylelint-config-css-modules": "^1.3.0",
"stylelint-config-standard": "^18.2.0", "stylelint-config-standard": "^18.2.0",
"tslint": "^5.12.1",
"tslint-config-prettier": "^1.17.0",
"tslint-react": "^3.6.0",
"typescript": "3.2.4" "typescript": "3.2.4"
}, },
"eslintConfig": { "eslintConfig": {

View File

@ -6,35 +6,28 @@ import { provideOcean } from './ocean'
import Routes from './Routes' import Routes from './Routes'
import './styles/global.scss' import './styles/global.scss'
import { import { nodeHost, nodePort, nodeScheme } from './config'
nodeHost,
nodePort,
nodeScheme
} from './config'
interface IState { interface AppState {
isLogged: boolean, isLogged: boolean
web3: any, web3: any
ocean: {}, ocean: {}
startLogin: () => void, startLogin: () => void
} }
class App extends Component<{},IState> { class App extends Component<{}, AppState> {
public startLogin: () => void public startLogin = (event?: any) => {
constructor(props: {}) { if (event) {
super(props) event.preventDefault()
this.startLogin = (event?) => {
if (event) {
event.preventDefault()
}
this.startLoginProcess()
}
this.state = {
isLogged: false,
web3: {},
ocean: {},
startLogin: this.startLogin,
} }
this.startLoginProcess()
}
public state = {
isLogged: false,
web3: {},
ocean: {},
startLogin: this.startLogin
} }
public async componentDidMount() { public async componentDidMount() {
@ -52,7 +45,7 @@ class App extends Component<{},IState> {
} }
private startLoginProcess = async () => { private startLoginProcess = async () => {
if((window as any).web3) { if ((window as any).web3) {
const web3 = new Web3((window as any).web3.currentProvider) const web3 = new Web3((window as any).web3.currentProvider)
try { try {
const accounts = await web3.eth.getAccounts() const accounts = await web3.eth.getAccounts()
@ -79,7 +72,7 @@ class App extends Component<{},IState> {
} }
private bootstrap = async () => { private bootstrap = async () => {
if((window as any).web3) { if ((window as any).web3) {
const web3 = new Web3((window as any).web3.currentProvider) const web3 = new Web3((window as any).web3.currentProvider)
try { try {
const accounts = await web3.eth.getAccounts() const accounts = await web3.eth.getAccounts()
@ -102,7 +95,11 @@ class App extends Component<{},IState> {
private setDefaultProvider = () => { private setDefaultProvider = () => {
this.setState(state => ({ this.setState(state => ({
isLogged: false, isLogged: false,
web3: new Web3(new Web3.providers.HttpProvider(`${nodeScheme}://${nodeHost}:${nodePort}`)) web3: new Web3(
new Web3.providers.HttpProvider(
`${nodeScheme}://${nodeHost}:${nodePort}`
)
)
})) }))
} }
} }

View File

@ -1,14 +1,15 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import styles from './Button.module.scss' import styles from './Button.module.scss'
interface IButtonProps { interface ButtonProps {
children: string children: string
primary?: boolean primary?: boolean
link?: boolean link?: boolean
href?: string href?: string
onClick?: any
} }
export default class Button extends PureComponent<IButtonProps, any> { export default class Button extends PureComponent<ButtonProps, any> {
public render() { public render() {
let classes let classes
const { primary, link, href, children, ...props } = this.props const { primary, link, href, children, ...props } = this.props

View File

@ -4,5 +4,7 @@ export const User = React.createContext({
isLogged: false, isLogged: false,
web3: {}, web3: {},
ocean: {}, ocean: {},
startLogin: () => {/* empty */} startLogin: () => {
/* empty */
}
}) })

View File

@ -1,40 +1,42 @@
const AssetModel = { const AssetModel = {
'assetId': null, assetId: null,
'publisherId': null, publisherId: null,
// OEP-08 Attributes // OEP-08 Attributes
// https://github.com/oceanprotocol/OEPs/tree/master/8 // https://github.com/oceanprotocol/OEPs/tree/master/8
'base': { base: {
'name': null, name: null,
'description': null, description: null,
'dateCreated': null, dateCreated: null,
'size': null, size: null,
'author': null, author: null,
'type': '', type: '',
'license': null, license: null,
'copyrightHolder': null, copyrightHolder: null,
'encoding': null, encoding: null,
'compression': null, compression: null,
'contentType': null, contentType: null,
'workExample': null, workExample: null,
'contentUrls': [], contentUrls: [],
'links': [{ links: [
'name': null, {
'type': null, name: null,
'url': null type: null,
}], url: null
'inLanguage': null, }
'tags': [], ],
'price': null inLanguage: null,
tags: [],
price: null
}, },
'curation': { curation: {
'rating': null, rating: null,
'numVotes': null, numVotes: null,
'schema': null schema: null
}, },
'additionalInformation': { additionalInformation: {
'updateFrequency': null, updateFrequency: null,
'structuredMarkup': [] structuredMarkup: []
} }
} }

View File

@ -1,6 +1,4 @@
import { import { Ocean } from '@oceanprotocol/squid/dist/node/squid'
Ocean
} from '@oceanprotocol/squid/dist/node/squid'
import { import {
address, address,

View File

@ -6,13 +6,11 @@ class About extends Component {
public render() { public render() {
return ( return (
<div className={styles.about}> <div className={styles.about}>
<Button>I am a button</Button> <Button>I am a button</Button>
<Button primary={true}>I am a primary button</Button> <Button primary>I am a primary button</Button>
<Button href="https://hello.com"> <Button href="https://hello.com">
I am a link disguised as a button I am a link disguised as a button
</Button> </Button>
</div> </div>
) )
} }

View File

@ -1,66 +1,78 @@
import { Logger } from '@oceanprotocol/squid' import { Logger } from '@oceanprotocol/squid'
import queryString from 'query-string'
import React, { Component } from 'react' import React, { Component } from 'react'
import Button from '../components/atoms/Button'
import { User } from '../context/User' import { User } from '../context/User'
interface IState { interface DetailsState {
ddo: any, ddo: any
metadata: any metadata: any
} }
interface IProps { interface DetailsProps {
location: any, location: any
match: any match: any
} }
class Details extends Component<IProps, IState> { export default class Details extends Component<DetailsProps, DetailsState> {
public state = { ddo: null, metadata: null } public state = { ddo: null, metadata: null }
public async componentDidMount() { public async componentDidMount() {
const ddo = await this.context.ocean.resolveDID(this.props.match.params.did) const ddo = await this.context.ocean.resolveDID(
const { metadata } = ddo.findServiceByType('Metadata') this.props.match.params.did
this.setState({ddo, metadata})
}
public render() {
return (
<>
{this.state.metadata ? (this.showDetails(this.state.ddo)): (<div>Loading</div>)}
</>
) )
const { metadata } = ddo.findServiceByType('Metadata')
this.setState({ ddo, metadata })
} }
private purchaseAsset = async (ddo: any) => { private purchaseAsset = async (ddo: any) => {
const account = await this.context.ocean.getAccounts() const account = await this.context.ocean.getAccounts()
const service = ddo.findServiceByType('Access') const service = ddo.findServiceByType('Access')
const serviceAgreementSignatureResult: any = await this.context.ocean const serviceAgreementSignatureResult: any = await this.context.ocean.signServiceAgreement(
.signServiceAgreement( ddo.id,
ddo.id, service.serviceDefinitionId,
service.serviceDefinitionId, account[0]
account[0]) )
Logger.log('serviceAgreementSignatureResult', serviceAgreementSignatureResult) Logger.log(
'serviceAgreementSignatureResult',
serviceAgreementSignatureResult
)
await this.context.ocean await this.context.ocean.initializeServiceAgreement(
.initializeServiceAgreement( ddo.id,
ddo.id, service.serviceDefinitionId,
service.serviceDefinitionId, serviceAgreementSignatureResult.serviceAgreementId,
serviceAgreementSignatureResult.serviceAgreementId, serviceAgreementSignatureResult.serviceAgreementSignature,
serviceAgreementSignatureResult.serviceAgreementSignature, (files: any) =>
(files: any) => Logger.log(`Got files, first files length in bytes: ${files[0].length}`), Logger.log(
account[0], `Got files, first files length in bytes: ${files[0].length}`
) ),
account[0]
)
} }
private showDetails = (ddo: any) => { private showDetails = (ddo: any) => {
return ( return (
<> <>
<div>{JSON.stringify(this.state.metadata)}</div> <div>{JSON.stringify(this.state.metadata)}</div>
<button onClick={this.purchaseAsset.bind(this, ddo)}>Purchase asset</button>
<Button onClick={this.purchaseAsset(ddo)}>
Purchase asset
</Button>
</>
)
}
public render() {
return (
<>
{this.state.metadata ? (
this.showDetails(this.state.ddo)
) : (
<div>Loading</div>
)}
</> </>
) )
} }
} }
Details.contextType = User Details.contextType = User
export default Details

View File

@ -3,16 +3,15 @@ import { Link } from 'react-router-dom'
import Button from '../components/atoms/Button' import Button from '../components/atoms/Button'
import styles from './Home.module.scss' import styles from './Home.module.scss'
interface IState { interface HomeState {
search?: string search?: string
} }
interface IProps { interface HomeProps {
history: any history: any
} }
class Home extends Component<IProps, IState> { class Home extends Component<HomeProps, HomeState> {
public state = { search: '' } public state = { search: '' }
public render() { public render() {
@ -24,11 +23,15 @@ class Home extends Component<IProps, IState> {
<div> <div>
<form onSubmit={this.searchAssets}> <form onSubmit={this.searchAssets}>
<input type="text" name="search" value={this.state.search} onChange={this.inputChange} /> <input
type="text"
name="search"
value={this.state.search}
onChange={this.inputChange}
/>
<Button>Search</Button> <Button>Search</Button>
</form> </form>
</div> </div>
</div> </div>
) )
} }

View File

@ -5,22 +5,21 @@ import AssetModel from '../models/AssetModel'
type AssetType = 'dataset' | 'algorithm' | 'container' | 'workflow' | 'other' type AssetType = 'dataset' | 'algorithm' | 'container' | 'workflow' | 'other'
interface IState { interface PublishState {
name?: string, name?: string
dateCreated?: Date, dateCreated?: Date
description?: string, description?: string
files?: string[], files?: string[]
price?: number, price?: number
author?: string, author?: string
type?: AssetType, type?: AssetType
license?: string, license?: string
copyrightHolder?: string, copyrightHolder?: string
categories?: string[], categories?: string[]
tags?: string[] tags?: string[]
} }
class Publish extends Component<{}, IState> { class Publish extends Component<{}, PublishState> {
public state = { public state = {
name: '', name: '',
dateCreated: new Date(), dateCreated: new Date(),
@ -31,7 +30,7 @@ class Publish extends Component<{}, IState> {
type: 'dataset' as AssetType, type: 'dataset' as AssetType,
license: '', license: '',
copyrightHolder: '', copyrightHolder: '',
categories: [''], categories: ['']
} }
public render() { public render() {
@ -39,89 +38,215 @@ class Publish extends Component<{}, IState> {
<div> <div>
<h1>Publish</h1> <h1>Publish</h1>
<form onSubmit={this.registerAsset}> <form onSubmit={this.registerAsset}>
<div>Name:<input type="text" name="name" value={this.state.name} onChange={this.inputChange} /></div> <div>
<div>Description:<input type="text" name="description" value={this.state.description} onChange={this.inputChange} /></div> Name:
<div>Price:<input type="number" name="price" value={this.state.price} onChange={this.inputChange} /></div> <input
<div>Author:<input type="text" name="author" value={this.state.author} onChange={this.inputChange} /></div> type="text"
<div>Files:<input type="text" name="files" value={this.state.files[0]} onChange={this.inputToArrayChange} /></div> name="name"
<div>Type: value={this.state.name}
<select name="type" value={this.state.type} onChange={this.inputChange}> onChange={this.inputChange}
<option value="dataset">Data set</option> />
<option value="algorithm">Algorithm</option> </div>
<option value="container">Container</option> <div>
<option value="workflow">Workflow</option> Description:
<option value="other">Other</option> <input
</select> type="text"
</div> name="description"
<div>License: value={this.state.description}
<select name="license" value={this.state.license} onChange={this.inputChange}> onChange={this.inputChange}
<option value="none">No License Specified</option> />
<option value="Public Domain">Public Domain</option> </div>
<option value="CC BY">CC BY: Attribution</option> <div>
<option value="CC BY-SA">CC BY-SA: Attribution ShareAlike</option> Price:
<option value="CC BY-ND">CC BY-ND: Attribution-NoDerivs</option> <input
<option value="CC BY-NC">CC BY-NC: Attribution-NonCommercial</option> type="number"
<option value="CC BY-NC-SA">CC BY-NC-SA: Attribution-NonCommercial-ShareAlike</option> name="price"
<option value="CC BY-NC-ND">CC BY-NC-ND: Attribution-NonCommercial-NoDerivs</option> value={this.state.price}
</select> onChange={this.inputChange}
</div> />
<div>Category: </div>
<select name="categories" value={this.state.categories[0]} onChange={this.inputToArrayChange}> <div>
<option value="No Category Specified">No Category Specified</option> Author:
<option value="Image Recognition">Image Recognition</option> <input
<option value="Dataset Of Datasets">Dataset Of Datasets</option> type="text"
<option value="Language">Language</option> name="author"
<option value="Performing Arts">Performing Arts</option> value={this.state.author}
<option value="Visual Arts & Design">Visual Arts & Design</option> onChange={this.inputChange}
<option value="Philosophy">Philosophy</option> />
<option value="History">History</option> </div>
<option value="Theology">Theology</option> <div>
<option value="Anthropology & Archeology">Anthropology & Archeology</option> Files:
<option value="Sociology">Sociology</option> <input
<option value="Psychology">Psychology</option> type="text"
<option value="Politics">Politics</option> name="files"
<option value="Interdisciplinary">Interdisciplinary</option> value={this.state.files[0]}
<option value="Economics & Finance">Economics & Finance</option> onChange={this.inputToArrayChange}
<option value="Demography">Demography</option> />
<option value="Biology">Biology</option> </div>
<option value="Chemistry">Chemistry</option> <div>
<option value="Physics & Energy">Physics & Energy</option> Type:
<option value="Earth & Climate">Earth & Climate</option> <select
<option value="Space & Astronomy">Space & Astronomy</option> name="type"
<option value="Mathematics">Mathematics</option> value={this.state.type}
<option value="Computer Technology">Computer Technology</option> onChange={this.inputChange}
<option value="Engineering">Engineering</option> >
<option value="Agriculture & Bio Engineering">Agriculture & Bio Engineering</option> <option value="dataset">Data set</option>
<option value="Transportation">Transportation</option> <option value="algorithm">Algorithm</option>
<option value="Urban Planning">Urban Planning</option> <option value="container">Container</option>
<option value="Medicine">Medicine</option> <option value="workflow">Workflow</option>
<option value="Language">Language</option> <option value="other">Other</option>
<option value="Business & Management">Business & Management</option> </select>
<option value="Sports & Recreation">Sports & Recreation</option> </div>
<option value="Communication & Journalism">Communication & Journalism</option> <div>
<option value="Other">Other</option> License:
</select> <select
</div> name="license"
<div>CopyrightHolder:<input type="text" name="copyrightHolder" value={this.state.copyrightHolder} onChange={this.inputChange} /></div> value={this.state.license}
<User.Consumer> onChange={this.inputChange}
{states => ( /* tslint:disable-next-line */ >
<div> <option value="none">No License Specified</option>
{states.isLogged ? (<div><Button>Register asset (we are logged)</Button></div>) : (<div><button onClick={states.startLogin}>Register asset (login first)</button></div>)} <option value="Public Domain">Public Domain</option>
</div> <option value="CC BY">CC BY: Attribution</option>
)} <option value="CC BY-SA">
</User.Consumer> CC BY-SA: Attribution ShareAlike
</option>
<option value="CC BY-ND">
CC BY-ND: Attribution-NoDerivs
</option>
<option value="CC BY-NC">
CC BY-NC: Attribution-NonCommercial
</option>
<option value="CC BY-NC-SA">
CC BY-NC-SA:
Attribution-NonCommercial-ShareAlike
</option>
<option value="CC BY-NC-ND">
CC BY-NC-ND: Attribution-NonCommercial-NoDerivs
</option>
</select>
</div>
<div>
Category:
<select
name="categories"
value={this.state.categories[0]}
onChange={this.inputToArrayChange}
>
<option value="No Category Specified">
No Category Specified
</option>
<option value="Image Recognition">
Image Recognition
</option>
<option value="Dataset Of Datasets">
Dataset Of Datasets
</option>
<option value="Language">Language</option>
<option value="Performing Arts">
Performing Arts
</option>
<option value="Visual Arts & Design">
Visual Arts & Design
</option>
<option value="Philosophy">Philosophy</option>
<option value="History">History</option>
<option value="Theology">Theology</option>
<option value="Anthropology & Archeology">
Anthropology & Archeology
</option>
<option value="Sociology">Sociology</option>
<option value="Psychology">Psychology</option>
<option value="Politics">Politics</option>
<option value="Interdisciplinary">
Interdisciplinary
</option>
<option value="Economics & Finance">
Economics & Finance
</option>
<option value="Demography">Demography</option>
<option value="Biology">Biology</option>
<option value="Chemistry">Chemistry</option>
<option value="Physics & Energy">
Physics & Energy
</option>
<option value="Earth & Climate">
Earth & Climate
</option>
<option value="Space & Astronomy">
Space & Astronomy
</option>
<option value="Mathematics">Mathematics</option>
<option value="Computer Technology">
Computer Technology
</option>
<option value="Engineering">Engineering</option>
<option value="Agriculture & Bio Engineering">
Agriculture & Bio Engineering
</option>
<option value="Transportation">
Transportation
</option>
<option value="Urban Planning">
Urban Planning
</option>
<option value="Medicine">Medicine</option>
<option value="Language">Language</option>
<option value="Business & Management">
Business & Management
</option>
<option value="Sports & Recreation">
Sports & Recreation
</option>
<option value="Communication & Journalism">
Communication & Journalism
</option>
<option value="Other">Other</option>
</select>
</div>
<div>
CopyrightHolder:
<input
type="text"
name="copyrightHolder"
value={this.state.copyrightHolder}
onChange={this.inputChange}
/>
</div>
<User.Consumer>
{(states /* tslint:disable-next-line */) => (
<div>
{states.isLogged ? (
<div>
<Button>
Register asset (we are logged)
</Button>
</div>
) : (
<div>
<button onClick={states.startLogin}>
Register asset (login first)
</button>
</div>
)}
</div>
)}
</User.Consumer>
</form> </form>
</div> </div>
) )
} }
private inputChange = (event: ChangeEvent<HTMLInputElement> | ChangeEvent<HTMLSelectElement>) => { private inputChange = (
event: ChangeEvent<HTMLInputElement> | ChangeEvent<HTMLSelectElement>
) => {
this.setState({ this.setState({
[event.target.name]: event.target.value [event.target.name]: event.target.value
}) })
} }
private inputToArrayChange = (event: ChangeEvent<HTMLInputElement> | ChangeEvent<HTMLSelectElement>) => { private inputToArrayChange = (
event: ChangeEvent<HTMLInputElement> | ChangeEvent<HTMLSelectElement>
) => {
this.setState({ this.setState({
[event.target.name]: [event.target.value] [event.target.name]: [event.target.value]
}) })
@ -136,7 +261,7 @@ class Publish extends Component<{}, IState> {
base: Object.assign(AssetModel.base, { base: Object.assign(AssetModel.base, {
name: this.state.name, name: this.state.name,
description: this.state.description, description: this.state.description,
dateCreated: (new Date()).toString(), dateCreated: new Date().toString(),
author: this.state.author, author: this.state.author,
license: this.state.license, license: this.state.license,
copyrightHolder: this.state.copyrightHolder, copyrightHolder: this.state.copyrightHolder,
@ -152,8 +277,11 @@ class Publish extends Component<{}, IState> {
tags: '' tags: ''
}), }),
curation: Object.assign(AssetModel.curation), curation: Object.assign(AssetModel.curation),
additionalInformation: Object.assign(AssetModel.additionalInformation) additionalInformation: Object.assign(
AssetModel.additionalInformation
)
} }
const ddo = await this.context.ocean.registerAsset(newAsset, account[0]) const ddo = await this.context.ocean.registerAsset(newAsset, account[0])
} }
} }

View File

@ -3,17 +3,16 @@ import React, { Component } from 'react'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import { provideOcean } from '../ocean' import { provideOcean } from '../ocean'
interface IState { interface SearchState {
results: any[] results: any[]
} }
interface IProps { interface SearchProps {
location: any, location: any
history: any history: any
} }
class Search extends Component<IProps, IState> { class Search extends Component<SearchProps, SearchState> {
public state = { results: [] } public state = { results: [] }
public async componentDidMount() { public async componentDidMount() {
@ -30,31 +29,31 @@ class Search extends Component<IProps, IState> {
} }
} }
const assets = await ocean.searchAssets(queryRequest) const assets = await ocean.searchAssets(queryRequest)
this.setState(state => ({results:assets})) this.setState(state => ({ results: assets }))
} }
public render() { public render() {
return ( return (
<> <>
{this.state.results.length ? (this.state.results.map(asset => this.renderAssetBox(asset))): (<div>No data sets yet</div>)} {this.state.results.length ? (
this.state.results.map(asset => this.renderAssetBox(asset))
) : (
<div>No data sets yet</div>
)}
</> </>
) )
} }
private renderAssetBox = (asset:any) => { private renderAssetBox = (asset: any) => {
const { metadata } = asset.findServiceByType('Metadata') const { metadata } = asset.findServiceByType('Metadata')
return ( return (
<div key={asset.id} onClick={this.openDetails.bind(this, asset.id)}> <Link key={asset.id} to={`/asset/${asset.id}`}>
<div>{asset.id}</div> <div>{asset.id}</div>
<div>{metadata.base.name}</div> <div>{metadata.base.name}</div>
<div>{metadata.base.description}</div> <div>{metadata.base.description}</div>
</div> </Link>
) )
} }
private openDetails = (assetId:string) => {
this.props.history.push(`/asset/${assetId}`)
}
} }
export default Search export default Search

View File

@ -1,4 +1,4 @@
/* tslint:disable */ /* eslint-disable */
// This optional code is used to register a service worker. // This optional code is used to register a service worker.
// register() is not called by default. // register() is not called by default.