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
2d07c42d
Commit
2d07c42d
authored
Oct 19, 2017
by
Jaden DIEFENBAUGH
Browse files
add db editor
parent
8c5c4972
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/components/DatabaseEditor.jsx
0 → 100644
View file @
2d07c42d
// @flow
import
*
as
React
from
'
react
'
;
import
{
Container
,
Row
,
Col
,
Button
,
Form
,
FormGroup
,
Label
,
Input
,
InputGroup
,
FormText
,
Collapse
,
Card
,
CardHeader
,
CardBody
,
TabContent
,
TabPane
,
Nav
,
NavItem
,
NavLink
,
CardTitle
,
CardText
,
FormFeedback
,
Alert
,
InputGroupAddon
,
UncontrolledDropdown
,
DropdownToggle
,
DropdownMenu
,
DropdownItem
,
ButtonGroup
,
}
from
'
reactstrap
'
;
import
{
connect
}
from
'
react-redux
'
;
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
{
BeatObject
,
}
from
'
@helpers/beat.js
'
;
import
{
nameValidator
}
from
'
@helpers/beat
'
;
import
{
changeObjFieldName
}
from
'
@helpers
'
;
type
Props
=
{
data
:
BeatObject
,
saveFunc
:
(
BeatObject
)
=>
any
,
databases
:
BeatObject
[],
dataformats
:
string
[],
};
type
State
=
{
cache
:
any
,
activeProtocol
:
number
,
};
const
mapStateToProps
:
MapStateToProps
<*
,
*
,
*>
=
(
state
,
ownProps
)
=>
{
const
obj
=
{
databases
:
Selectors
.
databaseGet
(
state
),
dataformats
:
Selectors
.
dataformatGet
(
state
).
map
(
d
=>
d
.
name
)
/*.concat(builtinDfs)*/
,
};
return
obj
;
};
const
getValidObj
=
(
data
=
{})
=>
{
const
getObj
=
{
name
:
''
,
contents
:
{},
...
JSON
.
parse
(
JSON
.
stringify
(
data
))
};
const
obj
=
{
...
getObj
,
contents
:
{
'
description
'
:
''
,
'
root_folder
'
:
''
,
'
protocols
'
:
[],
...
getObj
.
contents
,
},
};
return
obj
;
};
const
DeleteInputBtn
=
({
deleteFunc
}:
any
)
=>
(
<
span
className
=
'input-group-btn'
>
<
Button
color
=
'danger'
onClick
=
{
(
e
)
=>
deleteFunc
(
e
)
}
>
X
</
Button
>
</
span
>
);
class
DatabaseEditor
extends
React
.
Component
<
Props
,
State
>
{
constructor
(
props
:
Props
)
{
super
(
props
);
}
state
=
{
cache
:
getValidObj
(
this
.
props
.
data
),
activeProtocol
:
0
,
}
componentWillReceiveProps
(
nextProps
)
{
this
.
setState
({
cache
:
getValidObj
(
nextProps
.
data
),
});
}
setContents
=
(
newContents
)
=>
{
this
.
setState
({
cache
:
{
...
this
.
state
.
cache
,
contents
:
{
'
description
'
:
this
.
state
.
cache
.
contents
[
'
description
'
],
...
newContents
,
}
}
});
}
activateProtocol
=
(
index
:
number
)
=>
{
this
.
setState
({
activeProtocol
:
index
});
}
updateProtocol
=
(
index
:
number
,
obj
)
=>
{
this
.
setContents
({
...
this
.
state
.
cache
.
contents
,
protocols
:
this
.
state
.
cache
.
contents
.
protocols
.
map
((
o
,
i
)
=>
i
===
index
?
obj
:
o
)
});
}
updateSet
=
(
idxProtocol
:
number
,
idxSet
:
number
,
obj
)
=>
{
const
protocol
=
this
.
state
.
cache
.
contents
.
protocols
[
idxProtocol
];
this
.
updateProtocol
(
idxProtocol
,
{
...
protocol
,
sets
:
protocol
.
sets
.
map
((
s
,
i
)
=>
i
===
idxSet
?
obj
:
s
)
}
);
}
validatorFunc
=
nameValidator
(
'
database
'
,
this
.
props
.
databases
.
map
(
d
=>
d
.
name
));
nameIsValid
=
(
str
:
string
=
this
.
state
.
cache
.
name
)
=>
str
===
this
.
props
.
data
.
name
||
this
.
validatorFunc
(
str
);
renderProtocol
=
(
index
:
number
,
protocol
)
=>
(
<
Container
>
<
FormGroup
row
>
<
Col
sm
=
'2'
>
<
Label
for
=
'protocol-name'
className
=
'col-form-label'
>
Name
</
Label
>
</
Col
>
<
Col
sm
=
'10'
>
<
Input
name
=
'protocol-name'
placeholder
=
'Protocol name...'
value
=
{
protocol
.
name
}
onChange
=
{
(
e
)
=>
{
this
.
updateProtocol
(
index
,
{...
protocol
,
name
:
e
.
target
.
value
});
}
}
/>
</
Col
>
</
FormGroup
>
<
FormGroup
row
>
<
Col
sm
=
'2'
>
<
Label
for
=
'template'
className
=
'col-form-label'
>
Template Name
</
Label
>
</
Col
>
<
Col
sm
=
'10'
>
<
Input
name
=
'template'
placeholder
=
'Protocol Template name...'
value
=
{
protocol
.
template
}
onChange
=
{
(
e
)
=>
{
this
.
updateProtocol
(
index
,
{...
protocol
,
template
:
e
.
target
.
value
});
}
}
/>
</
Col
>
</
FormGroup
>
<
Row
>
<
Col
className
=
'd-flex align-items-center mb-2'
>
<
h3
className
=
'mb-0 mr-2'
>
Sets
</
h3
>
<
Button
outline
color
=
'success'
onClick
=
{
e
=>
{
const
newSets
=
[...
protocol
.
sets
,
{
name
:
''
,
template
:
''
,
view
:
''
,
outputs
:
{}
}];
this
.
updateProtocol
(
index
,
{
...
protocol
,
sets
:
newSets
}
);
}
}
>
+
</
Button
>
</
Col
>
</
Row
>
{
protocol
.
sets
.
map
((
currSet
,
i
)
=>
<
Row
key
=
{
i
}
>
<
Col
>
<
h4
>
{
currSet
.
name
}
{
'
'
}
<
ButtonGroup
>
<
Button
outline
color
=
'danger'
onClick
=
{
e
=>
{
this
.
updateProtocol
(
index
,
{
...
protocol
,
sets
:
protocol
.
sets
.
filter
((
s
,
j
)
=>
i
!==
j
)
}
);
}
}
>
Delete
</
Button
>
<
Button
outline
color
=
'secondary'
onClick
=
{
e
=>
{
const
newSets
=
[...
protocol
.
sets
];
newSets
.
splice
(
i
+
1
,
0
,
currSet
);
this
.
updateProtocol
(
index
,
{
...
protocol
,
sets
:
newSets
}
);
}
}
>
Clone
</
Button
>
</
ButtonGroup
>
</
h4
>
<
FormGroup
row
>
<
Col
sm
=
'2'
>
<
Label
for
=
{
`set-name-
${
i
}
`
}
className
=
'col-form-label'
>
Name
</
Label
>
</
Col
>
<
Col
sm
=
'10'
>
<
Input
name
=
{
`set-name-
${
i
}
`
}
placeholder
=
'Set name...'
value
=
{
currSet
.
name
}
onChange
=
{
(
e
)
=>
{
this
.
updateSet
(
index
,
i
,
{...
currSet
,
name
:
e
.
target
.
value
});
}
}
/>
</
Col
>
</
FormGroup
>
<
FormGroup
row
>
<
Col
sm
=
'2'
>
<
Label
for
=
{
`set-template-
${
i
}
`
}
className
=
'col-form-label'
>
Template Name
</
Label
>
</
Col
>
<
Col
sm
=
'10'
>
<
Input
name
=
{
`set-template-
${
i
}
`
}
placeholder
=
'Set Template name...'
value
=
{
currSet
.
template
}
onChange
=
{
(
e
)
=>
{
this
.
updateSet
(
index
,
i
,
{...
currSet
,
template
:
e
.
target
.
value
});
}
}
/>
</
Col
>
</
FormGroup
>
<
FormGroup
row
>
<
Col
sm
=
'2'
>
<
Label
for
=
{
`set-view-
${
i
}
`
}
className
=
'col-form-label'
>
View Name
</
Label
>
</
Col
>
<
Col
sm
=
'10'
>
<
Input
name
=
{
`set-view-
${
i
}
`
}
placeholder
=
'Set View name...'
value
=
{
currSet
.
view
}
onChange
=
{
(
e
)
=>
{
this
.
updateSet
(
index
,
i
,
{...
currSet
,
view
:
e
.
target
.
value
});
}
}
/>
</
Col
>
</
FormGroup
>
<
Container
>
<
Row
>
<
Col
sm
=
'6'
>
<
h6
>
Output Name
</
h6
>
</
Col
>
<
Col
sm
=
'6'
>
<
h6
>
Output Type
</
h6
>
</
Col
>
</
Row
>
{
Object
.
entries
(
currSet
.
outputs
).
map
(([
outputName
,
df
],
j
)
=>
<
FormGroup
row
key
=
{
j
}
>
<
Col
sm
=
'6'
>
<
CacheInput
value
=
{
outputName
}
validateFunc
=
{
(
str
)
=>
!
Object
.
keys
(
currSet
.
outputs
).
includes
(
str
)
}
onChange
=
{
e
=>
{
const
newOutputs
=
changeObjFieldName
(
currSet
.
outputs
,
outputName
,
e
.
target
.
value
);
this
.
updateSet
(
index
,
i
,
{
...
currSet
,
outputs
:
newOutputs
}
);
}
}
/>
</
Col
>
<
Col
sm
=
'6'
>
<
Input
type
=
'select'
className
=
'custom-select'
value
=
{
df
}
onChange
=
{
e
=>
{
this
.
updateSet
(
index
,
i
,
{
...
currSet
,
outputs
:
{
...
currSet
.
outputs
,
[
outputName
]:
e
.
target
.
value
}
}
);
}
}
>
<
option
disabled
value
=
''
>
Type...
</
option
>
{
this
.
props
.
dataformats
.
filter
(
d
=>
!
[
'
object
'
,
'
array
'
].
includes
(
d
))
.
map
((
d
,
i
)
=>
(
<
option
key
=
{
i
}
value
=
{
d
}
>
{
d
}
</
option
>
))
}
</
Input
>
</
Col
>
</
FormGroup
>
)
}
<
FormGroup
row
>
<
Button
outline
block
onClick
=
{
e
=>
{
let
newKey
=
''
;
let
v
=
0
;
while
(
true
)
{
const
tryKey
=
`Output
${
v
}
`
;
if
(
Object
.
keys
(
currSet
.
outputs
).
includes
(
tryKey
)){
v
++
;
continue
;
}
newKey
=
tryKey
;
break
;
}
this
.
updateSet
(
index
,
i
,
{
...
currSet
,
outputs
:
{
...
currSet
.
outputs
,
[
newKey
]:
'
string
'
}
});
}
}
>
New Output
</
Button
>
</
FormGroup
>
</
Container
>
</
Col
>
</
Row
>
)
}
</
Container
>
);
render
=
()
=>
(
<
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
=
'database'
obj
=
{
this
.
state
.
cache
}
/>
)
</
Button
>
</
div
>
<
Form
onSubmit
=
{
(
e
)
=>
e
.
preventDefault
()
}
>
<
FormGroup
tag
=
'fieldset'
>
<
FormGroup
>
<
Label
for
=
'dbName'
>
Name
</
Label
>
<
Input
type
=
'text'
name
=
'name'
id
=
'dbName'
placeholder
=
'New database name...'
value
=
{
this
.
state
.
cache
.
name
}
onChange
=
{
e
=>
this
.
setState
({
cache
:
{...
this
.
state
.
cache
,
'
name
'
:
e
.
target
.
value
}})
}
valid
=
{
this
.
nameIsValid
()
}
/>
</
FormGroup
>
<
FormGroup
>
<
Label
for
=
'description'
>
Short Description
</
Label
>
<
Input
type
=
'text'
name
=
'description'
placeholder
=
'Database description...'
value
=
{
this
.
state
.
cache
.
contents
[
'
description
'
]
}
onChange
=
{
e
=>
this
.
setContents
({
...
this
.
state
.
cache
.
contents
,
'
description
'
:
e
.
target
.
value
})
}
/>
</
FormGroup
>
</
FormGroup
>
<
div
className
=
'd-flex align-items-center mb-3'
>
<
h3
className
=
'mr-2 mb-0'
>
Protocols
</
h3
>
{
this
.
state
.
cache
.
contents
.
protocols
.
length
>
0
&&
<
UncontrolledDropdown
className
=
'mr-3'
>
<
DropdownToggle
outline
color
=
'secondary'
caret
className
=
''
>
Active Protocol:
{
this
.
state
.
cache
.
contents
.
protocols
[
this
.
state
.
activeProtocol
].
name
}
</
DropdownToggle
>
<
DropdownMenu
>
{
this
.
state
.
cache
.
contents
.
protocols
.
map
((
p
,
i
)
=>
<
DropdownItem
key
=
{
i
}
onClick
=
{
()
=>
this
.
activateProtocol
(
i
)
}
>
{
this
.
state
.
cache
.
contents
.
protocols
[
i
].
name
}{
'
'
}
(
{
this
.
state
.
cache
.
contents
.
protocols
[
i
].
template
}
)
</
DropdownItem
>
)
}
</
DropdownMenu
>
</
UncontrolledDropdown
>
}
<
ButtonGroup
>
<
Button
outline
color
=
'danger'
onClick
=
{
e
=>
{
const
active
=
this
.
state
.
activeProtocol
;
const
protocols
=
this
.
state
.
cache
.
contents
.
protocols
.
filter
((
p
,
i
)
=>
i
!==
active
);
this
.
setContents
({
...
this
.
state
.
cache
.
contents
,
protocols
});
this
.
activateProtocol
(
active
===
0
?
0
:
active
-
1
);
}
}
>
Delete
</
Button
>
<
Button
outline
color
=
'secondary'
onClick
=
{
e
=>
{
const
protocols
=
[...
this
.
state
.
cache
.
contents
.
protocols
];
protocols
.
splice
(
this
.
state
.
activeProtocol
+
1
,
0
,
protocols
[
this
.
state
.
activeProtocol
]
);
this
.
setContents
({
...
this
.
state
.
cache
.
contents
,
protocols
});
this
.
activateProtocol
(
this
.
state
.
activeProtocol
+
1
);
}
}
>
Clone
</
Button
>
<
Button
outline
color
=
'success'
onClick
=
{
e
=>
{
const
protocols
=
[...
this
.
state
.
cache
.
contents
.
protocols
,
{
name
:
''
,
template
:
''
,
sets
:
[],
}];
this
.
setContents
({
...
this
.
state
.
cache
.
contents
,
protocols
});
this
.
activateProtocol
(
protocols
.
length
-
1
);
}
}
>
New
</
Button
>
</
ButtonGroup
>
</
div
>
{
this
.
state
.
cache
.
contents
.
protocols
.
length
>
0
&&
this
.
renderProtocol
(
this
.
state
.
activeProtocol
,
this
.
state
.
cache
.
contents
.
protocols
[
this
.
state
.
activeProtocol
]
)
}
</
Form
>
</
div
>
);
}
export
default
connect
(
mapStateToProps
)(
DatabaseEditor
);
src/components/EntityDetail.jsx
View file @
2d07c42d
...
...
@@ -30,6 +30,7 @@ import ValidSchemaBadge from './ValidSchemaBadge.jsx';
import
DataformatEditor
from
'
./DataformatEditor.jsx
'
;
import
AlgorithmEditor
from
'
./AlgorithmEditor.jsx
'
;
import
LibraryEditor
from
'
./LibraryEditor.jsx
'
;
import
DatabaseEditor
from
'
./DatabaseEditor.jsx
'
;
type
Props
=
{
match
:
any
,
...
...
@@ -148,6 +149,13 @@ class EntityDetail extends React.Component<Props, State> {
saveFunc
=
{
this
.
saveChanges
}
/>
}
{
this
.
props
.
match
.
params
.
entity
===
'
database
'
&&
<
DatabaseEditor
data
=
{
this
.
props
.
getEntityObject
()
}
saveFunc
=
{
this
.
saveChanges
}
/>
}
</
TabPane
>
<
TabPane
tabId
=
'1'
>
<
Row
>
...
...
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