Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
beat
beat.editor
Commits
36e99c46
Commit
36e99c46
authored
Oct 18, 2017
by
Jaden DIEFENBAUGH
Browse files
added schema validation to details & editor, added save func for editors
parent
cf16a26c
Changes
9
Hide whitespace changes
Inline
Side-by-side
src/components/AlgorithmEditor.jsx
View file @
36e99c46
...
...
@@ -38,11 +38,14 @@ import { algorithmValidator } from '@helpers/beat.js';
import
type
{
AlgorithmValidatorObject
,
BeatObject
}
from
'
@helpers/beat.js
'
;
import
{
changeObjFieldName
}
from
'
@helpers
'
;
import
ValidSchemaBadge
from
'
./ValidSchemaBadge.jsx
'
;
type
Props
=
{
data
:
BeatObject
,
algorithms
:
BeatObject
[],
libraries
:
BeatObject
[],
dataformats
:
BeatObject
[],
saveFunc
:
(
BeatObject
)
=>
any
,
};
type
State
=
{
...
...
@@ -791,279 +794,291 @@ class AlgorithmEditor extends React.Component<Props, State> {
);
}
render
()
{
return
(
<
div
>
<
Form
>
<
FormGroup
tag
=
'fieldset'
>
<
legend
>
Algorithm Settings
</
legend
>
<
FormGroup
>
<
Label
for
=
'algName'
>
Name
</
Label
>
<
Input
type
=
'text'
name
=
'name'
id
=
'algName'
placeholder
=
'New algorithm name...'
valid
=
{
this
.
getValidity
().
name
}
value
=
{
this
.
state
.
cache
.
name
}
onChange
=
{
(
e
)
=>
this
.
updateName
(
e
.
target
.
value
)
}
/>
{
this
.
getValidity
().
name
?
''
:
<
Alert
color
=
'danger'
>
Please provide a
<
strong
>
unique
</
strong
>
name in the form
{
'
'
}
<
pre
style
=
{
{
display
:
'
inline
'
}
}
>
<
user
>
/
<
algorithm name
>
/
<
version number
>
</
pre
>
</
Alert
>
}
</
FormGroup
>
<
FormGroup
>
<
Label
for
=
'algDesc'
>
Short Description
</
Label
>
<
Input
type
=
'text'
name
=
'desc'
id
=
'algDesc'
placeholder
=
'Algorithm description...'
value
=
{
this
.
state
.
cache
.
contents
[
this
.
descField
()]
}
onChange
=
{
(
e
)
=>
this
.
changeContentsVal
(
this
.
descField
(),
e
.
target
.
value
)
}
/>
</
FormGroup
>
<
FormGroup
check
>
<
Label
check
>
renderLibraries
=
()
=>
(
<
TabPane
tabId
=
'2'
>
<
Row
>
<
Col
sm
=
'12'
>
{
Object
.
entries
(
this
.
state
.
cache
.
contents
.
uses
).
map
(([
name
,
lib
],
i
)
=>
(
<
GroupIOBlock
key
=
{
i
}
name
=
{
name
}
ioObj
=
{
lib
}
dfs
=
{
this
.
props
.
libraries
}
updateFunc
=
{
(
oldName
,
newName
,
obj
)
=>
{
const
libs
=
this
.
state
.
cache
.
contents
.
uses
;
delete
libs
[
oldName
];
libs
[
newName
]
=
obj
;
this
.
changeContentsVal
(
'
uses
'
,
libs
);
}
}
deleteFunc
=
{
(
name
)
=>
{
const
libs
=
this
.
state
.
cache
.
contents
.
uses
;
delete
libs
[
name
];
this
.
changeContentsVal
(
'
uses
'
,
libs
);
}
}
lazyFunc
=
{
(
str
,
updateFunc
)
=>
this
.
lazyInputUpdate
(
this
.
state
.
cache
.
contents
.
uses
,
str
,
updateFunc
)
}
/>
))
}
</
Col
>
</
Row
>
<
Button
outline
block
onClick
=
{
()
=>
this
.
changeContentsVal
(
'
uses
'
,
{
...
this
.
state
.
cache
.
contents
.
uses
,
[
`library_
${
Object
.
keys
(
this
.
state
.
cache
.
contents
.
uses
).
length
}
`
]:
''
})
}
>
New Library
</
Button
>
</
TabPane
>
);
renderResults
=
()
=>
(
<
TabPane
tabId
=
'3'
>
{
Object
.
entries
(
this
.
state
.
cache
.
contents
.
results
)
.
map
(([
name
,
result
],
i
)
=>
(
<
FormGroup
row
key
=
{
i
}
>
<
Col
sm
=
'4'
>
<
InputGroup
>
<
DeleteInputBtn
deleteFunc
=
{
()
=>
{
delete
this
.
state
.
cache
.
contents
.
results
[
name
];
this
.
changeContentsVal
(
'
results
'
,
this
.
state
.
cache
.
contents
.
results
);
}
}
/>
<
Input
type
=
'checkbox'
checked
=
{
this
.
isAnalyzer
()
}
onChange
=
{
e
=>
e
.
target
.
checked
?
this
.
changeToAnalyzer
()
:
this
.
changeToNormal
()
}
/>
{
'
'
}
Analyser
</
Label
>
</
FormGroup
>
<
FormGroup
check
>
type
=
'text'
placeholder
=
'Result name...'
value
=
{
name
}
onChange
=
{
(
e
)
=>
this
.
lazyInputUpdate
(
this
.
state
.
cache
.
contents
.
results
,
e
.
target
.
value
,
()
=>
this
.
changeContentsVal
(
'
results
'
,
changeObjFieldName
(
this
.
state
.
cache
.
contents
.
results
,
name
,
e
.
target
.
value
)
)
)
}
/>
</
InputGroup
>
</
Col
>
<
Col
sm
=
'4'
>
<
Input
type
=
'select'
className
=
'custom-select'
value
=
{
result
.
type
}
onChange
=
{
(
e
)
=>
this
.
updateResult
(
name
,
{
...
result
,
type
:
e
.
target
.
value
})
}
>
<
option
disabled
value
=
''
>
Type...
</
option
>
{
this
.
state
.
resultDfs
.
map
((
d
,
i
)
=>
(
<
option
key
=
{
i
}
value
=
{
d
}
>
{
d
}
</
option
>
))
}
</
Input
>
</
Col
>
<
Col
>
<
Label
check
>
<
Input
type
=
'checkbox'
checked
=
{
this
.
state
.
cache
.
contents
.
splittable
?
true
:
false
}
onChange
=
{
e
=>
this
.
changeContentsVal
(
'
splittable
'
,
e
.
target
.
checked
)
}
/>
{
'
'
}
Splittable
value
=
{
result
.
display
?
true
:
false
}
onChange
=
{
(
e
)
=>
this
.
changeContentsVal
(
'
results
'
,
{
...
this
.
state
.
cache
.
contents
.
results
,
[
name
]
:
{
...
result
,
display
:
e
.
target
.
checked
}
})
}
/>
{
'
'
}
<
span
>
Display By Default
</
span
>
</
Label
>
</
FormGroup
>
</
Col
>
</
FormGroup
>
{
(
!
this
.
isAnalyzer
()
||
this
.
getValidity
().
result0Exists
)
||
<
Alert
color
=
'danger'
>
You need at least 1 result from an Analyzer.
</
Alert
>
}
{
this
.
getValidity
().
endpoint0Exists
||
<
Alert
color
=
'danger'
>
You need at least 1 endpoint group.
</
Alert
>
}
{
this
.
getValidity
().
endpointNamesUnique
||
<
Alert
color
=
'danger'
>
Each endpoint group should have a different name.
</
Alert
>
}
{
(
this
.
isAnalyzer
()
||
this
.
getValidity
().
endpoint0OutputExists
)
||
<
Alert
color
=
'danger'
>
You must have at least 1 output
in the first endpoint group.
</
Alert
>
}
{
this
.
getValidity
().
endpoint0InputExists
||
<
Alert
color
=
'danger'
>
You need at least 1 input in the first endpoint group.
</
Alert
>
))
}
<
Button
outline
block
onClick
=
{
()
=>
this
.
changeContentsVal
(
'
results
'
,
{...
this
.
state
.
cache
.
contents
.
results
,
[
`result
${
Object
.
keys
(
this
.
state
.
cache
.
contents
.
results
).
length
}
`
]:
{
display
:
false
,
type
:
''
}
}
<
div
className
=
'mt-3 mb-3'
>
<
Nav
tabs
>
<
NavItem
>
<
NavLink
className
=
{
cn
({
active
:
this
.
state
.
activeTab
===
'
0
'
})
}
onClick
=
{
()
=>
this
.
tabTo
(
'
0
'
)
}
>
Endpoints
</
NavLink
>
</
NavItem
>
<
NavItem
>
<
NavLink
className
=
{
cn
({
active
:
this
.
state
.
activeTab
===
'
1
'
})
}
onClick
=
{
()
=>
this
.
tabTo
(
'
1
'
)
}
>
Parameters
</
NavLink
>
</
NavItem
>
)
}
>
New Result
</
Button
>
</
TabPane
>
);
render
=
()
=>
(
<
div
className
=
'mt-1'
>
<
div
className
=
'd-flex'
>
<
Button
className
=
'mx-auto'
outline
color
=
'secondary'
onClick
=
{
()
=>
this
.
props
.
saveFunc
(
this
.
state
.
cache
)
}
>
Save Changes (Cache is
<
ValidSchemaBadge
entity
=
'algorithm'
obj
=
{
this
.
state
.
cache
}
/>
)
</
Button
>
</
div
>
<
Form
>
<
FormGroup
tag
=
'fieldset'
>
<
FormGroup
>
<
Label
for
=
'algName'
>
Name
</
Label
>
<
Input
type
=
'text'
name
=
'name'
id
=
'algName'
placeholder
=
'New algorithm name...'
valid
=
{
this
.
getValidity
().
name
}
value
=
{
this
.
state
.
cache
.
name
}
onChange
=
{
(
e
)
=>
this
.
updateName
(
e
.
target
.
value
)
}
/>
{
this
.
getValidity
().
name
?
''
:
<
Alert
color
=
'danger'
>
Please provide a
<
strong
>
unique
</
strong
>
name in the form
{
'
'
}
<
pre
style
=
{
{
display
:
'
inline
'
}
}
>
<
user
>
/
<
algorithm name
>
/
<
version number
>
</
pre
>
</
Alert
>
}
</
FormGroup
>
<
FormGroup
>
<
Label
for
=
'algDesc'
>
Short Description
</
Label
>
<
Input
type
=
'text'
name
=
'desc'
id
=
'algDesc'
placeholder
=
'Algorithm description...'
value
=
{
this
.
state
.
cache
.
contents
[
this
.
descField
()]
}
onChange
=
{
(
e
)
=>
this
.
changeContentsVal
(
this
.
descField
(),
e
.
target
.
value
)
}
/>
</
FormGroup
>
<
FormGroup
check
>
<
Label
check
>
<
Input
type
=
'checkbox'
checked
=
{
this
.
isAnalyzer
()
}
onChange
=
{
e
=>
e
.
target
.
checked
?
this
.
changeToAnalyzer
()
:
this
.
changeToNormal
()
}
/>
{
'
'
}
Analyser
</
Label
>
</
FormGroup
>
<
FormGroup
check
>
<
Label
check
>
<
Input
type
=
'checkbox'
checked
=
{
this
.
state
.
cache
.
contents
.
splittable
?
true
:
false
}
onChange
=
{
e
=>
this
.
changeContentsVal
(
'
splittable
'
,
e
.
target
.
checked
)
}
/>
{
'
'
}
Splittable
</
Label
>
</
FormGroup
>
</
FormGroup
>
{
(
!
this
.
isAnalyzer
()
||
this
.
getValidity
().
result0Exists
)
||
<
Alert
color
=
'danger'
>
You need at least 1 result from an Analyzer.
</
Alert
>
}
{
this
.
getValidity
().
endpoint0Exists
||
<
Alert
color
=
'danger'
>
You need at least 1 endpoint group.
</
Alert
>
}
{
this
.
getValidity
().
endpointNamesUnique
||
<
Alert
color
=
'danger'
>
Each endpoint group should have a different name.
</
Alert
>
}
{
(
this
.
isAnalyzer
()
||
this
.
getValidity
().
endpoint0OutputExists
)
||
<
Alert
color
=
'danger'
>
You must have at least 1 output
in the first endpoint group.
</
Alert
>
}
{
this
.
getValidity
().
endpoint0InputExists
||
<
Alert
color
=
'danger'
>
You need at least 1 input in the first endpoint group.
</
Alert
>
}
<
div
className
=
'mt-3 mb-3'
>
<
Nav
tabs
>
<
NavItem
>
<
NavLink
className
=
{
cn
({
active
:
this
.
state
.
activeTab
===
'
0
'
})
}
onClick
=
{
()
=>
this
.
tabTo
(
'
0
'
)
}
>
Endpoints
</
NavLink
>
</
NavItem
>
<
NavItem
>
<
NavLink
className
=
{
cn
({
active
:
this
.
state
.
activeTab
===
'
1
'
})
}
onClick
=
{
()
=>
this
.
tabTo
(
'
1
'
)
}
>
Parameters
</
NavLink
>
</
NavItem
>
<
NavItem
>
<
NavLink
className
=
{
cn
({
active
:
this
.
state
.
activeTab
===
'
2
'
})
}
onClick
=
{
()
=>
this
.
tabTo
(
'
2
'
)
}
>
Libraries
</
NavLink
>
</
NavItem
>
{
this
.
state
.
cache
.
contents
.
results
?
(
<
NavItem
>
<
NavLink
className
=
{
cn
({
active
:
this
.
state
.
activeTab
===
'
2
'
})
}
onClick
=
{
()
=>
this
.
tabTo
(
'
2
'
)
}
className
=
{
cn
({
active
:
this
.
state
.
activeTab
===
'
3
'
})
}
onClick
=
{
()
=>
this
.
tabTo
(
'
3
'
)
}
>
Librarie
s
Result
s
</
NavLink
>
</
NavItem
>
{
this
.
state
.
cache
.
contents
.
results
?
(
<
NavItem
>
<
NavLink
className
=
{
cn
({
active
:
this
.
state
.
activeTab
===
'
3
'
})
}
onClick
=
{
()
=>
this
.
tabTo
(
'
3
'
)
}
>
Results
</
NavLink
>
</
NavItem
>
)
:
''
}
</
Nav
>
<
TabContent
className
=
'mt-3'
activeTab
=
{
this
.
state
.
activeTab
}
>
{
this
.
renderEndpoints
()
}
{
this
.
renderParameters
()
}
<
TabPane
tabId
=
'2'
>
<
Row
>
<
Col
sm
=
'12'
>
{
Object
.
entries
(
this
.
state
.
cache
.
contents
.
uses
).
map
(([
name
,
lib
],
i
)
=>
(
<
GroupIOBlock
key
=
{
i
}
name
=
{
name
}
ioObj
=
{
lib
}
dfs
=
{
this
.
props
.
libraries
}
updateFunc
=
{
(
oldName
,
newName
,
obj
)
=>
{
const
libs
=
this
.
state
.
cache
.
contents
.
uses
;
delete
libs
[
oldName
];
libs
[
newName
]
=
obj
;
this
.
changeContentsVal
(
'
uses
'
,
libs
);
}
}
deleteFunc
=
{
(
name
)
=>
{
const
libs
=
this
.
state
.
cache
.
contents
.
uses
;
delete
libs
[
name
];
this
.
changeContentsVal
(
'
uses
'
,
libs
);
}
}
lazyFunc
=
{
(
str
,
updateFunc
)
=>
this
.
lazyInputUpdate
(
this
.
state
.
cache
.
contents
.
uses
,
str
,
updateFunc
)
}
/>
))
}
</
Col
>
</
Row
>
<
Button
outline
block
onClick
=
{
()
=>
this
.
changeContentsVal
(
'
uses
'
,
{
...
this
.
state
.
cache
.
contents
.
uses
,
[
`library_
${
Object
.
keys
(
this
.
state
.
cache
.
contents
.
uses
).
length
}
`
]:
''
})
}
>
New Library
</
Button
>
</
TabPane
>
{
this
.
state
.
cache
.
contents
.
results
?
(
<
TabPane
tabId
=
'3'
>
{
Object
.
entries
(
this
.
state
.
cache
.
contents
.
results
)
.
map
(([
name
,
result
],
i
)
=>
(
<
FormGroup
row
key
=
{
i
}
>
<
Col
sm
=
'4'
>
<
InputGroup
>
<
DeleteInputBtn
deleteFunc
=
{
()
=>
{
delete
this
.
state
.
cache
.
contents
.
results
[
name
];
this
.
changeContentsVal
(
'
results
'
,
this
.
state
.
cache
.
contents
.
results
);
}
}
/>
<
Input
type
=
'text'
placeholder
=
'Result name...'
value
=
{
name
}
onChange
=
{
(
e
)
=>
this
.
lazyInputUpdate
(
this
.
state
.
cache
.
contents
.
results
,
e
.
target
.
value
,
()
=>
this
.
changeContentsVal
(
'
results
'
,
changeObjFieldName
(
this
.
state
.
cache
.
contents
.
results
,
name
,
e
.
target
.
value
)
)
)
}
/>
</
InputGroup
>
</
Col
>
<
Col
sm
=
'4'
>
<
Input
type
=
'select'
className
=
'custom-select'
value
=
{
result
.
type
}
onChange
=
{
(
e
)
=>
this
.
updateResult
(
name
,
{
...
result
,
type
:
e
.
target
.
value
})
}
>
<
option
disabled
value
=
''
>
Type...
</
option
>
{
this
.
state
.
resultDfs
.
map
((
d
,
i
)
=>
(
<
option
key
=
{
i
}
value
=
{
d
}
>
{
d
}
</
option
>
))
}
</
Input
>
</
Col
>
<
Col
>
<
Label
check
>
<
Input
type
=
'checkbox'
value
=
{
result
.
display
?
true
:
false
}
onChange
=
{
(
e
)
=>
this
.
changeContentsVal
(
'
results
'
,
{
...
this
.
state
.
cache
.
contents
.
results
,
[
name
]
:
{
...
result
,
display
:
e
.
target
.
checked
}
})
}
/>
{
'
'
}
<
span
>
Display By Default
</
span
>
</
Label
>
</
Col
>
</
FormGroup
>
))
}
<
Button
outline
block
onClick
=
{
()
=>
this
.
changeContentsVal
(
'
results
'
,
{...
this
.
state
.
cache
.
contents
.
results
,
[
`result
${
Object
.
keys
(
this
.
state
.
cache
.
contents
.
results
).
length
}
`
]:
{
display
:
false
,
type
:
''
}
}
)
}
>
New Result
</
Button
>
</
TabPane
>
)
:
''
}
</
TabContent
>
</
div
>
</
Form
>
</
div
>
);
}
)
:
''
}
</
Nav
>
<
TabContent
className
=
'mt-3'
activeTab
=
{
this
.
state
.
activeTab
}
>
{
this
.
renderEndpoints
()
}
{
this
.
renderParameters
()
}
{
this
.
renderLibraries
()
}
{
this
.
state
.
cache
.
contents
.
results
&&
this
.
renderResults
()
}
</
TabContent
>
</
div
>
</
Form
>
</
div
>
);
}
export
default
connect
(
mapStateToProps
)(
AlgorithmEditor
);
src/components/DataformatEditor.jsx
View file @
36e99c46
...
...
@@ -26,6 +26,7 @@ import type { MapStateToProps, MapDispatchToProps } from 'react-redux';
import
*
as
Selectors
from
'
@store/selectors.js
'
;
import
ValidSchemaBadge
from
'
./ValidSchemaBadge.jsx
'
;
import
CacheInput
from
'
./CacheInput.jsx
'
;
import
type
{
...
...
@@ -38,6 +39,7 @@ type Props = {
data
:
BeatObject
,
dfs
:
BeatObject
[],
dataformats
:
string
[],
saveFunc
:
(
BeatObject
)
=>
any
,
};
type
State
=
{
...
...
@@ -343,38 +345,49 @@ class DataformatEditor extends React.Component<Props, State> {
}
render
=
()
=>
(
<
Form
onSubmit
=
{
(
e
)
=>
e
.
preventDefault
()
}
>
<
FormGroup
tag
=
'fieldset'
>
<
legend
>
Dataformat Settings
</
legend
>
<
FormGroup
>
<
Label
for
=
'dfName'
>
Name
</
Label
>
<
Input
type
=
'text'
name
=
'name'
id
=
'dfName'
placeholder
=
'New dataformat name...'
value
=
{
this
.
state
.
cache
.
name
}
onChange
=
{
e
=>
this
.
setState
({
cache
:
{...
this
.
state
.
cache
,
'
name
'
:
e
.
target
.
value
}})
}