mirror of
https://github.com/oceanprotocol/commons.git
synced 2023-03-15 18:03:00 +01:00
Merge pull request #44 from oceanprotocol/feature/datepicker
Add date picker, ask for dateCreated
This commit is contained in:
commit
7e340cca07
32
client/package-lock.json
generated
32
client/package-lock.json
generated
@ -1400,6 +1400,16 @@
|
||||
"csstype": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"@types/react-datepicker": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-datepicker/-/react-datepicker-2.2.0.tgz",
|
||||
"integrity": "sha512-zVAeDqkQgSdARElFXwXXpaaADyoRMo1SPsBzw6WV2iciJqS3ysSvYjqEKyTZfGbGkgw5sExEI2QKXam/KlCtyg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/react": "*",
|
||||
"popper.js": "^1.14.1"
|
||||
}
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"version": "16.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.8.3.tgz",
|
||||
@ -5470,6 +5480,11 @@
|
||||
"whatwg-url": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"date-fns": {
|
||||
"version": "2.0.0-alpha.27",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.0.0-alpha.27.tgz",
|
||||
"integrity": "sha512-cqfVLS+346P/Mpj2RpDrBv0P4p2zZhWWvfY5fuWrXNR/K38HaAGEkeOwb47hIpQP9Jr/TIxjZ2/sNMQwdXuGMg=="
|
||||
},
|
||||
"date-now": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
|
||||
@ -15893,6 +15908,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-datepicker": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-2.3.0.tgz",
|
||||
"integrity": "sha512-sgauGBTUlVrne5oHuYeLhBtKy2YOuEbPo/rXRTuxP/dRJNkHpXQ+ZfRmiJDX30mh/+EGRW5ORLVGhD1YgLbEiA==",
|
||||
"requires": {
|
||||
"classnames": "^2.2.5",
|
||||
"date-fns": "^2.0.0-alpha.23",
|
||||
"prop-types": "^15.6.0",
|
||||
"react-onclickoutside": "^6.7.1",
|
||||
"react-popper": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"react-dev-utils": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-8.0.0.tgz",
|
||||
@ -16113,6 +16140,11 @@
|
||||
"resolved": "https://registry.npmjs.org/react-moment/-/react-moment-0.8.4.tgz",
|
||||
"integrity": "sha512-QhI19OcfhiAn60/O6bMR0w8ApXrPFCjv6+eV0I/P9/AswzjgEAx4L7VxMBCpS/jrythLa12Q9v88req+ys4YpA=="
|
||||
},
|
||||
"react-onclickoutside": {
|
||||
"version": "6.8.0",
|
||||
"resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.8.0.tgz",
|
||||
"integrity": "sha512-5Q4Rn7QLEoh7WIe66KFvYIpWJ49GeHoygP1/EtJyZjXKgrWH19Tf0Ty3lWyQzrEEDyLOwUvvmBFSE3dcDdvagA=="
|
||||
},
|
||||
"react-popper": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.3.tgz",
|
||||
|
@ -19,6 +19,7 @@
|
||||
"moment": "^2.24.0",
|
||||
"query-string": "^6.4.2",
|
||||
"react": "^16.8.6",
|
||||
"react-datepicker": "^2.3.0",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-helmet": "^5.2.0",
|
||||
"react-moment": "^0.8.4",
|
||||
@ -35,6 +36,7 @@
|
||||
"@types/jest": "^24.0.11",
|
||||
"@types/query-string": "^6.3.0",
|
||||
"@types/react": "^16.8.10",
|
||||
"@types/react-datepicker": "^2.2.0",
|
||||
"@types/react-dom": "^16.8.3",
|
||||
"@types/react-helmet": "^5.0.8",
|
||||
"@types/react-router-dom": "^4.3.1",
|
||||
|
@ -1,4 +1,5 @@
|
||||
@import '../../../styles/variables';
|
||||
@import './InputDate.module.scss';
|
||||
|
||||
.inputWrap {
|
||||
background: $brand-gradient;
|
||||
@ -10,6 +11,11 @@
|
||||
&.isFocused {
|
||||
background: $brand-black;
|
||||
}
|
||||
|
||||
> div,
|
||||
> div > div {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.inputWrapSearch {
|
||||
|
@ -1,12 +1,14 @@
|
||||
import cx from 'classnames'
|
||||
import React, { PureComponent } from 'react'
|
||||
import React, { PureComponent, FormEvent, ChangeEvent } from 'react'
|
||||
import slugify from 'slugify'
|
||||
import DatePicker from 'react-datepicker'
|
||||
import { ReactComponent as SearchIcon } from '../../../img/search.svg'
|
||||
import Help from './Help'
|
||||
import styles from './Input.module.scss'
|
||||
import Label from './Label'
|
||||
import Row from './Row'
|
||||
import InputGroup from './InputGroup'
|
||||
import 'react-datepicker/dist/react-datepicker-cssmodules.css'
|
||||
import styles from './Input.module.scss'
|
||||
|
||||
interface InputProps {
|
||||
name: string
|
||||
@ -19,7 +21,13 @@ interface InputProps {
|
||||
options?: string[]
|
||||
additionalComponent?: any
|
||||
value?: string
|
||||
onChange?: any
|
||||
onChange?(
|
||||
event:
|
||||
| FormEvent<HTMLInputElement>
|
||||
| ChangeEvent<HTMLInputElement>
|
||||
| ChangeEvent<HTMLSelectElement>
|
||||
| ChangeEvent<HTMLTextAreaElement>
|
||||
): void
|
||||
rows?: number
|
||||
group?: any
|
||||
multiple?: boolean
|
||||
@ -27,10 +35,14 @@ interface InputProps {
|
||||
|
||||
interface InputState {
|
||||
isFocused: boolean
|
||||
startDate?: Date
|
||||
}
|
||||
|
||||
export default class Input extends PureComponent<InputProps, InputState> {
|
||||
public state: InputState = { isFocused: false }
|
||||
public state: InputState = {
|
||||
isFocused: false,
|
||||
startDate: new Date()
|
||||
}
|
||||
|
||||
public inputWrapClasses() {
|
||||
if (this.props.type === 'search') {
|
||||
@ -48,6 +60,12 @@ export default class Input extends PureComponent<InputProps, InputState> {
|
||||
this.setState({ isFocused: !this.state.isFocused })
|
||||
}
|
||||
|
||||
public handleDateChange = (date: Date) => {
|
||||
this.setState({
|
||||
startDate: date
|
||||
})
|
||||
}
|
||||
|
||||
public InputComponent = () => {
|
||||
const {
|
||||
type,
|
||||
@ -61,7 +79,8 @@ export default class Input extends PureComponent<InputProps, InputState> {
|
||||
|
||||
const wrapClass = this.inputWrapClasses()
|
||||
|
||||
if (type === 'select') {
|
||||
switch (type) {
|
||||
case 'select':
|
||||
return (
|
||||
<div className={wrapClass}>
|
||||
<select
|
||||
@ -91,7 +110,7 @@ export default class Input extends PureComponent<InputProps, InputState> {
|
||||
</select>
|
||||
</div>
|
||||
)
|
||||
} else if (type === 'textarea') {
|
||||
case 'textarea':
|
||||
return (
|
||||
<div className={wrapClass}>
|
||||
<textarea
|
||||
@ -103,7 +122,8 @@ export default class Input extends PureComponent<InputProps, InputState> {
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
} else if (type === 'radio' || type === 'checkbox') {
|
||||
case 'radio':
|
||||
case 'checkbox':
|
||||
return (
|
||||
<div className={styles.radioGroup}>
|
||||
{options &&
|
||||
@ -132,6 +152,18 @@ export default class Input extends PureComponent<InputProps, InputState> {
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
case 'date':
|
||||
return (
|
||||
<div className={wrapClass}>
|
||||
<DatePicker
|
||||
selected={this.state.startDate}
|
||||
onChange={this.handleDateChange}
|
||||
className={styles.input}
|
||||
onFocus={this.toggleFocus}
|
||||
onBlur={this.toggleFocus}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
|
69
client/src/components/atoms/Form/InputDate.module.scss
Normal file
69
client/src/components/atoms/Form/InputDate.module.scss
Normal file
@ -0,0 +1,69 @@
|
||||
@import '../../../styles/variables';
|
||||
|
||||
//
|
||||
// Date picker
|
||||
//
|
||||
:global .react-datepicker {
|
||||
font-family: inherit;
|
||||
color: inherit;
|
||||
border-color: $brand-black;
|
||||
}
|
||||
|
||||
:global .react-datepicker__header {
|
||||
background: $brand-black;
|
||||
border-radius: 0;
|
||||
|
||||
.react-datepicker__day-name,
|
||||
.react-datepicker__day,
|
||||
.react-datepicker__time-name,
|
||||
.react-datepicker__current-month,
|
||||
.react-datepicker-time__header,
|
||||
.react-datepicker-year-header {
|
||||
color: $brand-white;
|
||||
}
|
||||
}
|
||||
|
||||
:global .react-datepicker__current-month,
|
||||
:global .react-datepicker-time__header,
|
||||
:global .react-datepicker-year-header,
|
||||
:global .react-datepicker__day-name {
|
||||
font-weight: $font-weight-bold;
|
||||
}
|
||||
|
||||
:global .react-datepicker__month-container {
|
||||
float: none;
|
||||
}
|
||||
|
||||
:global .react-datepicker-popper {
|
||||
max-width: 16rem;
|
||||
}
|
||||
|
||||
:global .react-datepicker-popper[data-placement^='top'] .react-datepicker__triangle:before,
|
||||
:global .react-datepicker__year-read-view--down-arrow:before,
|
||||
:global .react-datepicker__month-read-view--down-arrow:before,
|
||||
:global .react-datepicker__month-year-read-view--down-arrow:before {
|
||||
border-top-color: $brand-black;
|
||||
}
|
||||
|
||||
:global .react-datepicker__day--selected,
|
||||
:global .react-datepicker__day--in-selecting-range,
|
||||
:global .react-datepicker__day--in-range,
|
||||
:global .react-datepicker__month-text--selected,
|
||||
:global .react-datepicker__month-text--in-selecting-range,
|
||||
:global .react-datepicker__month-text--in-range {
|
||||
background-color: $brand-black;
|
||||
border-radius: 50%;
|
||||
font-weight: $font-weight-bold;
|
||||
}
|
||||
|
||||
:global .react-datepicker__day:hover,
|
||||
:global .react-datepicker__month-text:hover {
|
||||
background-color: $brand-pink;
|
||||
border-radius: 50%;
|
||||
font-weight: $font-weight-bold;
|
||||
color: $brand-white;
|
||||
}
|
||||
|
||||
:global .react-datepicker__day--outside-month {
|
||||
color: $brand-grey-light;
|
||||
}
|
@ -26,7 +26,7 @@
|
||||
"fields": {
|
||||
"description": {
|
||||
"label": "Description",
|
||||
"description": "Add a thorough description with as much detail as possible.",
|
||||
"help": "Add a thorough description with as much detail as possible.",
|
||||
"placeholder": "i.e. Almond sales data ",
|
||||
"type": "textarea",
|
||||
"required": true,
|
||||
@ -34,7 +34,7 @@
|
||||
},
|
||||
"categories": {
|
||||
"label": "Categories",
|
||||
"description": "Pick a category which best fits your data set.",
|
||||
"help": "Pick a category which best fits your data set.",
|
||||
"type": "select",
|
||||
"required": true,
|
||||
"options": [
|
||||
@ -70,6 +70,12 @@
|
||||
"Communication & Journalism",
|
||||
"Other"
|
||||
]
|
||||
},
|
||||
"dateCreated": {
|
||||
"label": "Creation Date",
|
||||
"help": "Select the date the asset was created, or was updated for the last time.",
|
||||
"type": "date",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -38,6 +38,12 @@
|
||||
"type": "select",
|
||||
"required": true,
|
||||
"options": ["Automotive", "Technology"]
|
||||
},
|
||||
"date": {
|
||||
"label": "Date",
|
||||
"placeholder": "i.e. 2019-08-12",
|
||||
"type": "date",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,15 @@ export default class AssetDetails extends PureComponent<AssetDetailsProps> {
|
||||
{base.copyrightHolder}
|
||||
</h2>
|
||||
<div className={styles.metaPrimaryData}>
|
||||
|
||||
<span title="Date created">
|
||||
<Moment
|
||||
date={base.dateCreated}
|
||||
format="L"
|
||||
interval={0}
|
||||
/>
|
||||
</span>
|
||||
|
||||
{base.categories ? (
|
||||
// TODO: Make this link to search for respective category
|
||||
<Link to={`/search?q=${base.categories[0]}`}>
|
||||
@ -34,14 +43,6 @@ export default class AssetDetails extends PureComponent<AssetDetailsProps> {
|
||||
<Link to={'/search?q='}>Fake Category</Link>
|
||||
)}
|
||||
|
||||
<span title="Date published">
|
||||
<Moment
|
||||
date={base.dateCreated}
|
||||
format="L"
|
||||
interval={0}
|
||||
/>
|
||||
</span>
|
||||
|
||||
{base.files && (
|
||||
<span>{base.files.length} data files</span>
|
||||
)}
|
||||
|
@ -2,7 +2,13 @@ import React from 'react'
|
||||
import styles from './Item.module.scss'
|
||||
import filesize from 'filesize'
|
||||
|
||||
const Item = ({ item, removeItem }: { item: any; removeItem: any }) => (
|
||||
const Item = ({
|
||||
item,
|
||||
removeItem
|
||||
}: {
|
||||
item: { url: string; found: boolean; type: string; size: number }
|
||||
removeItem(): void
|
||||
}) => (
|
||||
<li>
|
||||
<a href={item.url} className={styles.linkUrl}>
|
||||
{item.url}
|
||||
|
@ -5,7 +5,7 @@ import Button from '../../../components/atoms/Button'
|
||||
import styles from './ItemForm.module.scss'
|
||||
|
||||
interface ItemFormProps {
|
||||
addItem: any
|
||||
addItem(url: string): void
|
||||
placeholder: string
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { PureComponent } from 'react'
|
||||
import React, { FormEvent, PureComponent, ChangeEvent } from 'react'
|
||||
import { CSSTransition, TransitionGroup } from 'react-transition-group'
|
||||
import Button from '../../../components/atoms/Button'
|
||||
import Help from '../../../components/atoms/Form/Help'
|
||||
@ -10,9 +10,10 @@ import { serviceHost, servicePort, serviceScheme } from '../../../config'
|
||||
|
||||
interface File {
|
||||
url: string
|
||||
found: boolean
|
||||
checksum?: string
|
||||
checksumType?: string
|
||||
contentLength?: string
|
||||
contentLength?: number
|
||||
contentType?: string
|
||||
resourceId?: string
|
||||
encoding?: string
|
||||
@ -24,7 +25,13 @@ interface FilesProps {
|
||||
placeholder: string
|
||||
help?: string
|
||||
name: string
|
||||
onChange: any
|
||||
onChange(
|
||||
event:
|
||||
| ChangeEvent<HTMLInputElement>
|
||||
| FormEvent<HTMLInputElement>
|
||||
| ChangeEvent<HTMLSelectElement>
|
||||
| ChangeEvent<HTMLTextAreaElement>
|
||||
): void
|
||||
}
|
||||
|
||||
interface FilesStates {
|
||||
@ -70,7 +77,14 @@ export default class Files extends PureComponent<FilesProps, FilesStates> {
|
||||
|
||||
public addItem = async (value: string) => {
|
||||
let res: any
|
||||
let file: any = { url: value, found: false }
|
||||
let file: File = {
|
||||
url: value,
|
||||
found: false,
|
||||
contentLength: 0,
|
||||
contentType: '',
|
||||
compression: ''
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${serviceScheme}://${serviceHost}:${servicePort}/api/v1/urlcheck`,
|
||||
@ -85,7 +99,7 @@ export default class Files extends PureComponent<FilesProps, FilesStates> {
|
||||
res = await response.json()
|
||||
file.contentLength = res.result.contentLength
|
||||
file.contentType = res.result.contentType
|
||||
file.compression = await getFileCompression(file.contentType)
|
||||
file.compression = await getFileCompression(res.result.contentType)
|
||||
file.found = res.result.found
|
||||
} catch (error) {
|
||||
// error
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { PureComponent } from 'react'
|
||||
import React, { PureComponent, FormEvent, ChangeEvent } from 'react'
|
||||
import Input from '../../components/atoms/Form/Input'
|
||||
import Label from '../../components/atoms/Form/Label'
|
||||
import Row from '../../components/atoms/Form/Row'
|
||||
@ -8,20 +8,38 @@ import Files from './Files/'
|
||||
import StepRegisterContent from './StepRegisterContent'
|
||||
import styles from './Step.module.scss'
|
||||
|
||||
interface Fields {
|
||||
label: string
|
||||
placeholder?: string
|
||||
help?: string
|
||||
type: string
|
||||
required?: boolean
|
||||
options?: string
|
||||
rows?: number
|
||||
}
|
||||
|
||||
interface StepProps {
|
||||
currentStep: number
|
||||
index: number
|
||||
inputChange: any
|
||||
inputToArrayChange: any
|
||||
fields?: any[]
|
||||
inputChange(
|
||||
event:
|
||||
| FormEvent<HTMLInputElement>
|
||||
| ChangeEvent<HTMLInputElement>
|
||||
| ChangeEvent<HTMLSelectElement>
|
||||
| ChangeEvent<HTMLTextAreaElement>
|
||||
): void
|
||||
inputToArrayChange(
|
||||
event: ChangeEvent<HTMLSelectElement> | ChangeEvent<HTMLInputElement>
|
||||
): void
|
||||
fields?: Fields
|
||||
state: any
|
||||
title: string
|
||||
description: string
|
||||
next: any
|
||||
prev: any
|
||||
next(): void
|
||||
prev(): void
|
||||
totalSteps: number
|
||||
tryAgain: any
|
||||
toStart: any
|
||||
tryAgain(): void
|
||||
toStart(): void
|
||||
publishedDid?: string
|
||||
content?: string
|
||||
}
|
||||
@ -66,7 +84,6 @@ export default class Step extends PureComponent<StepProps, {}> {
|
||||
description,
|
||||
fields,
|
||||
inputChange,
|
||||
inputToArrayChange,
|
||||
state,
|
||||
totalSteps,
|
||||
tryAgain,
|
||||
@ -89,7 +106,6 @@ export default class Step extends PureComponent<StepProps, {}> {
|
||||
|
||||
{fields &&
|
||||
Object.entries(fields).map(([key, value]) => {
|
||||
|
||||
if (key === 'files') {
|
||||
return (
|
||||
<Row key={key}>
|
||||
|
@ -4,8 +4,8 @@ import Spinner from '../../components/atoms/Spinner'
|
||||
import styles from './StepRegisterContent.module.scss'
|
||||
|
||||
interface StepRegisterContentProps {
|
||||
tryAgain: any
|
||||
toStart: any
|
||||
tryAgain(): void
|
||||
toStart(): void
|
||||
state: any
|
||||
content?: string
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ type AssetType = 'dataset' | 'algorithm' | 'container' | 'workflow' | 'other'
|
||||
|
||||
interface PublishState {
|
||||
name?: string
|
||||
dateCreated?: Date
|
||||
dateCreated?: string
|
||||
description?: string
|
||||
files?: string[]
|
||||
price?: number
|
||||
@ -35,7 +35,7 @@ class Publish extends Component<{}, PublishState> {
|
||||
public state = {
|
||||
currentStep: 1,
|
||||
name: '',
|
||||
dateCreated: new Date(),
|
||||
dateCreated: '',
|
||||
description: '',
|
||||
files: [],
|
||||
price: 0,
|
||||
@ -50,7 +50,12 @@ class Publish extends Component<{}, PublishState> {
|
||||
publishingError: '',
|
||||
validationStatus: {
|
||||
1: { name: false, files: false, allFieldsValid: false },
|
||||
2: { description: false, categories: false, allFieldsValid: false },
|
||||
2: {
|
||||
description: false,
|
||||
categories: false,
|
||||
dateCreated: false,
|
||||
allFieldsValid: false
|
||||
},
|
||||
3: {
|
||||
author: false,
|
||||
copyrightHolder: false,
|
||||
@ -102,7 +107,7 @@ class Publish extends Component<{}, PublishState> {
|
||||
private toStart = () => {
|
||||
this.setState({
|
||||
name: '',
|
||||
dateCreated: new Date(),
|
||||
dateCreated: '',
|
||||
description: '',
|
||||
files: [],
|
||||
price: 0,
|
||||
@ -184,7 +189,11 @@ class Publish extends Component<{}, PublishState> {
|
||||
//
|
||||
// Step 2
|
||||
//
|
||||
if (validationStatus[2].description && validationStatus[2].categories) {
|
||||
if (
|
||||
validationStatus[2].description &&
|
||||
validationStatus[2].categories &&
|
||||
validationStatus[2].dateCreated
|
||||
) {
|
||||
this.setState(prevState => ({
|
||||
validationStatus: {
|
||||
...prevState.validationStatus,
|
||||
@ -250,7 +259,7 @@ class Publish extends Component<{}, PublishState> {
|
||||
base: Object.assign(AssetModel.base, {
|
||||
name: this.state.name,
|
||||
description: this.state.description,
|
||||
dateCreated: new Date().toString(),
|
||||
dateCreated: new Date(this.state.dateCreated).toISOString(),
|
||||
author: this.state.author,
|
||||
license: this.state.license,
|
||||
copyrightHolder: this.state.copyrightHolder,
|
||||
|
Loading…
Reference in New Issue
Block a user