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
02b0c85c
Commit
02b0c85c
authored
Apr 10, 2018
by
Jaden DIEFENBAUGH
Browse files
add plotter editor,
#82
parent
40cec9fb
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/components/EntityDetail.jsx
View file @
02b0c85c
...
...
@@ -33,6 +33,7 @@ import LibraryEditorContainer from './library';
import
DatabaseEditorContainer
from
'
./database
'
;
import
ExperimentEditorContainer
from
'
./experiment
'
;
import
ToolchainEditorContainer
from
'
./toolchain
'
;
import
PlotterEditorContainer
from
'
./plotter
'
;
type
Props
=
{
match
:
any
,
...
...
@@ -155,6 +156,13 @@ export class EntityDetail extends React.Component<Props, State> {
saveFunc
=
{
this
.
saveChanges
}
/>
}
{
this
.
props
.
match
.
params
.
entity
===
'
plotter
'
&&
<
PlotterEditorContainer
data
=
{
this
.
props
.
getEntityObject
()
}
saveFunc
=
{
this
.
saveChanges
}
/>
}
</
TabPane
>
<
TabPane
tabId
=
'1'
>
<
Row
>
...
...
src/components/plotter/PlotterEditor.jsx
0 → 100644
View file @
02b0c85c
// @flow
import
*
as
React
from
'
react
'
;
import
{
Row
,
Col
,
Button
,
Form
,
FormGroup
,
Label
,
Input
,
Card
,
CardHeader
,
CardBody
,
TabContent
,
TabPane
,
Nav
,
NavItem
,
NavLink
,
Alert
,
UncontrolledDropdown
,
DropdownToggle
,
DropdownMenu
,
InputGroup
,
InputGroupAddon
,
}
from
'
reactstrap
'
;
import
{
connect
}
from
'
react-redux
'
;
import
cn
from
'
classnames
'
;
import
{
changeObjFieldName
,
generateNewKey
,
jsonClone
}
from
'
@helpers
'
;
import
{
BUILTIN_TYPES
,
ANALYZER_RESULT_TYPES
,
getValidPlotterObj
as
getValidObj
}
from
'
@helpers/beat
'
;
import
type
{
BeatObject
}
from
'
@helpers/beat
'
;
import
*
as
Selectors
from
'
@store/selectors.js
'
;
import
CacheInput
from
'
../CacheInput.jsx
'
;
import
ValidSchemaBadge
from
'
../ValidSchemaBadge.jsx
'
;
import
DeleteInputBtn
from
'
../DeleteInputBtn.jsx
'
;
import
TypedField
from
'
../TypedField.jsx
'
;
import
TemplateButton
from
'
../EntityTemplateGenerationButton.jsx
'
;
import
InfoTooltip
from
'
../InfoTooltip.jsx
'
;
type
Props
=
{
data
:
BeatObject
,
libraries
:
BeatObject
[],
plotDfNames
:
string
[],
saveFunc
:
(
BeatObject
)
=>
any
,
};
type
State
=
{
cache
:
any
,
choiceCache
:
string
,
};
export
class
PlotterEditor
extends
React
.
Component
<
Props
,
State
>
{
constructor
(
props
:
Props
)
{
//console.log(`Creating AlgDetail`);
super
(
props
);
}
state
=
{
cache
:
getValidObj
(
this
.
props
.
data
),
choiceCache
:
''
,
}
componentWillReceiveProps
(
nextProps
:
Props
)
{
this
.
setState
({
cache
:
getValidObj
(
nextProps
.
data
),
});
}
setContents
=
(
newContents
:
any
)
=>
{
this
.
setState
({
cache
:
{
...
this
.
state
.
cache
,
contents
:
{
...
this
.
state
.
cache
.
contents
,
...
newContents
,
}
}
});
}
updateDescription
=
(
desc
:
string
)
=>
{
this
.
setContents
({
description
:
desc
});
}
updateDataformat
=
(
df
:
string
)
=>
{
this
.
setContents
({
dataformat
:
df
});
}
// 4 different functions:
// creates a parameter (provide name & value)
// updates a parameter (provide name & value)
// renames a parameter (provide name & value & the old name)
// deletes a parameter (provide null as name, value is optional, the name)
updateParameter
=
(
name
:
null
|
string
,
value
:
any
,
oldName
:
?
string
)
=>
{
const
params
=
jsonClone
(
this
.
state
.
cache
.
contents
.
parameters
);
if
(
oldName
)
delete
params
[
oldName
];
if
(
name
!==
null
)
params
[
name
]
=
value
;
this
.
setContents
({
parameters
:
params
});
}
render
=
()
=>
{
return
(
<
div
>
<
div
className
=
'd-flex'
>
<
Button
className
=
'mx-auto'
outline
color
=
'secondary'
onClick
=
{
()
=>
this
.
props
.
saveFunc
(
this
.
state
.
cache
)
}
>
Save Changes (Changes are
<
ValidSchemaBadge
entity
=
'plotter'
obj
=
{
this
.
state
.
cache
}
/>
)
</
Button
>
{
/*
<TemplateButton
data={this.state.cache}
entity={'plotter'}
/>
*/
}
</
div
>
<
Form
>
<
FormGroup
tag
=
'fieldset'
>
<
FormGroup
>
<
Label
>
Short Description
</
Label
>
<
Input
type
=
'text'
id
=
'plDesc'
placeholder
=
'Plotter description...'
value
=
{
this
.
state
.
cache
.
contents
.
description
}
onChange
=
{
(
e
)
=>
this
.
updateDescription
(
e
.
target
.
value
)
}
/>
</
FormGroup
>
<
FormGroup
>
<
Label
>
Input Dataformat
</
Label
>
<
Input
id
=
'plDf'
type
=
'select'
className
=
'custom-select'
value
=
{
this
.
state
.
cache
.
contents
.
dataformat
}
onChange
=
{
e
=>
this
.
updateDataformat
(
e
.
target
.
value
)
}
>
{
this
.
props
.
plotDfNames
.
map
((
df
,
i
)
=>
<
option
key
=
{
i
}
value
=
{
df
}
>
{
df
}
</
option
>
)
}
</
Input
>
</
FormGroup
>
<
FormGroup
>
<
h5
>
Parameters
</
h5
>
{
(
Object
.
entries
(
this
.
state
.
cache
.
contents
.
parameters
):
[
string
,
any
][]).
map
(([
name
,
param
],
i
,
params
)
=>
(
<
Row
key
=
{
i
}
className
=
'mb-2'
>
<
Col
sm
=
'12'
>
<
TypedField
placeholder
=
'Parameter name...'
name
=
{
name
}
type
=
{
param
.
type
}
types
=
{
BUILTIN_TYPES
.
filter
(
d
=>
!
d
.
startsWith
(
'
complex
'
))
}
existingFields
=
{
params
.
map
(([
n
,
v
])
=>
n
)
}
nameUpdateFunc
=
{
str
=>
this
.
updateParameter
(
str
,
param
,
name
)
}
typeUpdateFunc
=
{
(
str
)
=>
{
const
newParam
=
{
...
param
,
type
:
str
};
switch
(
newParam
.
type
){
case
'
string
'
:
delete
newParam
[
'
range
'
];
break
;
case
'
bool
'
:
delete
newParam
[
'
range
'
];
delete
newParam
[
'
choice
'
];
break
;
default
:
break
;
}
this
.
updateParameter
(
name
,
newParam
);
}
}
deleteFunc
=
{
()
=>
{
this
.
updateParameter
(
null
,
null
,
name
);
}
}
>
<
Col
>
<
Input
type
=
'text'
placeholder
=
'Description'
value
=
{
param
[
name
]
||
param
.
description
||
''
}
onChange
=
{
(
e
)
=>
this
.
updateParameter
(
name
,
{
...
param
,
description
:
e
.
target
.
value
})
}
/>
</
Col
>
</
TypedField
>
<
FormGroup
row
className
=
'ml-3'
>
{
param
.
type
!==
'
bool
'
&&
<
Col
sm
=
'4'
>
<
Label
>
Restrict to...
</
Label
>
<
FormGroup
check
>
<
Row
>
<
Col
>
<
Label
check
>
<
Input
type
=
'checkbox'
checked
=
{
Array
.
isArray
(
param
.
choice
)
}
onChange
=
{
e
=>
{
const
b
=
e
.
target
.
checked
;
const
newParam
=
{...
param
};
if
(
b
){
delete
newParam
[
'
range
'
];
newParam
[
'
choice
'
]
=
[];
}
else
{
delete
newParam
[
'
choice
'
];
}
this
.
updateParameter
(
name
,
newParam
);
}
}
/>
{
'
'
}
Choices
</
Label
>
</
Col
>
{
param
.
type
!==
'
string
'
&&
<
Col
>
<
Label
check
className
=
'ml-3'
>
<
Input
type
=
'checkbox'
checked
=
{
Array
.
isArray
(
param
.
range
)
}
onChange
=
{
e
=>
{
const
b
=
e
.
target
.
checked
;
const
newParam
=
{...
param
};
if
(
b
){
delete
newParam
[
'
choice
'
];
newParam
[
'
range
'
]
=
[
0
,
1
];
}
else
{
delete
newParam
[
'
range
'
];
}
this
.
updateParameter
(
name
,
newParam
);
}
}
/>
{
'
'
}
Range
</
Label
>
</
Col
>
}
</
Row
>
</
FormGroup
>
</
Col
>
}
{
Array
.
isArray
(
param
.
choice
)
&&
<
Col
sm
=
'auto'
>
<
Label
>
Choices
</
Label
>
<
UncontrolledDropdown
>
<
DropdownToggle
caret
>
Choices List
</
DropdownToggle
>
<
DropdownMenu
className
=
'p-0'
>
{
param
.
choice
.
map
((
c
,
j
)
=>
<
InputGroup
key
=
{
j
}
>
<
Input
defaultValue
=
{
c
}
className
=
'border-top-0 border-left-0 border-right-0 rounded-0'
onSubmit
=
{
e
=>
{
e
.
preventDefault
();
}
}
onChange
=
{
e
=>
{
this
.
updateParameter
(
name
,
{
...
param
,
choice
:
param
.
choice
.
map
((
c
,
k
)
=>
k
===
j
?
e
.
target
.
value
:
c
)
});
}
}
/>
<
InputGroupAddon
addonType
=
'append'
>
<
Button
className
=
'border-top-0 border-left-0 border-right-0 rounded-0'
color
=
'danger'
onClick
=
{
e
=>
{
this
.
updateParameter
(
name
,
{
...
param
,
choice
:
param
.
choice
.
filter
((
c
,
k
)
=>
k
!==
j
)
}
);
}
}
>
x
</
Button
>
</
InputGroupAddon
>
</
InputGroup
>
)
}
<
Input
placeholder
=
'New Choice...'
className
=
'border-top-0 border-left-0 border-right-0 rounded-0'
value
=
{
this
.
state
.
choiceCache
}
onSubmit
=
{
e
=>
{
e
.
preventDefault
();
}
}
onBlur
=
{
e
=>
{
if
(
this
.
state
.
choiceCache
.
length
>
0
)
this
.
updateParameter
(
name
,
{
...
param
,
choice
:
[
...
param
.
choice
,
this
.
state
.
choiceCache
]
});
this
.
setState
({
choiceCache
:
''
});
}
}
onChange
=
{
e
=>
{
this
.
setState
({
choiceCache
:
e
.
target
.
value
});
}
}
onKeyPress
=
{
e
=>
{
if
(
e
.
key
===
'
Enter
'
){
if
(
this
.
state
.
choiceCache
.
length
>
0
)
this
.
updateParameter
(
name
,
{
...
param
,
choice
:
[
...
param
.
choice
,
this
.
state
.
choiceCache
]
}
);
this
.
setState
({
choiceCache
:
''
});
}
}
}
/>
</
DropdownMenu
>
</
UncontrolledDropdown
>
</
Col
>
}
{
Array
.
isArray
(
param
.
range
)
&&
<
Col
sm
=
'4'
>
<
Label
>
Range
</
Label
>
<
FormGroup
row
>
<
Col
>
<
InputGroup
>
<
InputGroupAddon
>
Min
</
InputGroupAddon
>
<
Input
type
=
'number'
step
=
{
param
.
type
.
startsWith
(
'
float
'
)
?
'
any
'
:
'
1
'
}
value
=
{
param
.
range
[
0
]
}
onChange
=
{
e
=>
{
const
num
=
e
.
target
.
value
;
const
newParam
=
{
...
param
,
range
:
[
num
,
param
.
range
[
1
],
]
};
this
.
updateParameter
(
name
,
newParam
);
}
}
required
/>
</
InputGroup
>
</
Col
>
<
Col
>
<
InputGroup
>
<
InputGroupAddon
>
Max
</
InputGroupAddon
>
<
Input
type
=
'number'
step
=
{
param
.
type
.
startsWith
(
'
float
'
)
?
'
any
'
:
'
1
'
}
value
=
{
param
.
range
[
1
]
}
required
onChange
=
{
e
=>
{
const
num
=
e
.
target
.
value
;
const
newParam
=
{
...
param
,
range
:
[
param
.
range
[
0
],
num
,
]
};
this
.
updateParameter
(
name
,
newParam
);
}
}
/>
</
InputGroup
>
</
Col
>
</
FormGroup
>
</
Col
>
}
{
param
.
type
!==
'
bool
'
&&
<
Col
>
<
Label
for
=
{
`default
${
i
}
`
}
>
Default
</
Label
>
<
Input
name
=
{
`default
${
i
}
`
}
type
=
'text'
placeholder
=
'Default'
value
=
{
param
.
default
}
onChange
=
{
(
e
)
=>
this
.
updateParameter
(
name
,
{
...
param
,
default
:
e
.
target
.
value
})
}
/>
</
Col
>
||
<
Col
sm
=
'auto'
>
<
Label
>
Default
</
Label
>
<
FormGroup
check
>
<
Row
>
<
Col
>
<
Label
check
>
<
Input
name
=
{
`default
${
i
}
`
}
type
=
'radio'
/>
True
</
Label
>
</
Col
>
<
Col
>
<
Label
check
className
=
'ml-1'
>
<
Input
name
=
{
`default
${
i
}
`
}
type
=
'radio'
/>
False
</
Label
>
</
Col
>
</
Row
>
</
FormGroup
>
</
Col
>
}
</
FormGroup
>
</
Col
>
</
Row
>
))
}
<
Button
outline
block
id
=
'newParameterBtn'
onClick
=
{
()
=>
{
const
newKey
=
generateNewKey
(
'
parameter
'
,
Object
.
keys
(
this
.
state
.
cache
.
contents
.
parameters
||
{}));
this
.
updateParameter
(
newKey
,
{
type
:
''
,
default
:
''
,
description
:
''
,
}
);
}
}
>
New Parameter
</
Button
>
</
FormGroup
>
</
FormGroup
>
</
Form
>
</
div
>
);
}
}
const
mapStateToProps
=
(
state
,
ownProps
)
=>
{
const
obj
=
{
plotters
:
Selectors
.
plotterGet
(
state
),
libraries
:
Selectors
.
libraryGet
(
state
),
plotDfNames
:
Selectors
.
dataformatGet
(
state
).
map
(
df
=>
df
.
name
).
filter
(
df
=>
df
.
startsWith
(
'
plot/
'
)),
};
return
obj
;
};
export
default
connect
(
mapStateToProps
)(
PlotterEditor
);
src/components/plotter/PlotterEditor.spec.jsx
0 → 100644
View file @
02b0c85c
src/components/plotter/index.js
0 → 100644
View file @
02b0c85c
// @flow
import
ConnectedPlotterEditor
,
{
PlotterEditor
}
from
'
./PlotterEditor.jsx
'
;
export
{
PlotterEditor
,
};
export
default
ConnectedPlotterEditor
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment