-
diff --git a/browser/main/Components/SnippetEditModal.jsx b/browser/main/Components/SnippetEditModal.jsx
new file mode 100644
index 00000000..f09242a5
--- /dev/null
+++ b/browser/main/Components/SnippetEditModal.jsx
@@ -0,0 +1,38 @@
+var React = require('react')
+var SnippetForm = require('./SnippetForm')
+var PlanetStore = require('../Stores/PlanetStore')
+
+var SnippetEditModal = React.createClass({
+ propTypes: {
+ close: React.PropTypes.func,
+ snippet: React.PropTypes.object
+ },
+ componentDidMount: function () {
+ this.unsubscribe = PlanetStore.listen(this.onListen)
+ },
+ componentWillUnmount: function () {
+ this.unsubscribe()
+ },
+ onListen: function (res) {
+ switch (res.status) {
+ case 'snippetUpdated':
+ this.props.close()
+ break
+ }
+ },
+ stopPropagation: function (e) {
+ e.stopPropagation()
+ },
+ render: function () {
+ return (
+
+ )
+ }
+})
+
+module.exports = SnippetEditModal
diff --git a/browser/main/Components/SnippetForm.jsx b/browser/main/Components/SnippetForm.jsx
index 2895b5c3..1b4598dc 100644
--- a/browser/main/Components/SnippetForm.jsx
+++ b/browser/main/Components/SnippetForm.jsx
@@ -31,17 +31,19 @@ var getOptions = function (input, callback) {
var SnippetForm = React.createClass({
mixins: [Catalyst.LinkedStateMixin, ReactRouter.State],
propTypes: {
- close: React.PropTypes.func
+ close: React.PropTypes.func,
+ snippet: React.PropTypes.object
},
getInitialState: function () {
+ var snippet = Object.assign({
+ description: '',
+ mode: 'javascript',
+ content: '',
+ callSign: '',
+ Tags: []
+ }, this.props.snippet)
return {
- snippet: {
- description: '',
- mode: 'javascript',
- content: '',
- callSign: '',
- Tags: []
- }
+ snippet: snippet
}
},
componentDidMount: function () {
@@ -58,14 +60,22 @@ var SnippetForm = React.createClass({
this.setState({snippet: snippet})
},
submit: function () {
- var params = this.getParams()
- var userName = params.userName
- var planetName = params.planetName
var snippet = Object.assign({}, this.state.snippet)
snippet.Tags = snippet.Tags.map(function (tag) {
return tag.value
})
- PlanetActions.createSnippet(userName + '/' + planetName, snippet)
+ if (this.props.snippet == null) {
+ var params = this.getParams()
+ var userName = params.userName
+ var planetName = params.planetName
+
+ PlanetActions.createSnippet(userName + '/' + planetName, snippet)
+ } else {
+ var snippetId = snippet.id
+ delete snippet.id
+
+ PlanetActions.updateSnippet(snippetId, snippet)
+ }
},
render: function () {
return (
diff --git a/browser/main/Containers/PlanetContainer.jsx b/browser/main/Containers/PlanetContainer.jsx
index 2f4f5ea0..df1e22c9 100644
--- a/browser/main/Containers/PlanetContainer.jsx
+++ b/browser/main/Containers/PlanetContainer.jsx
@@ -3,6 +3,7 @@ var ReactRouter = require('react-router')
var ModalBase = require('../Components/ModalBase')
var LaunchModal = require('../Components/LaunchModal')
var CodeViewer = require('../Components/CodeViewer')
+var SnippetEditModal = require('../Components/SnippetEditModal')
var AuthStore = require('../Stores/AuthStore')
var PlanetStore = require('../Stores/PlanetStore')
@@ -160,6 +161,20 @@ var PlanetArticleDetail = React.createClass({
propTypes: {
snippet: React.PropTypes.object
},
+ getInitialState: function () {
+ return {
+ isEditModalOpen: false
+ }
+ },
+ openEditModal: function () {
+ this.setState({isEditModalOpen: true})
+ },
+ closeEditModal: function () {
+ this.setState({isEditModalOpen: false})
+ },
+ submitEditModal: function () {
+ this.setState({isEditModalOpen: false})
+ },
render: function () {
var snippet = this.props.snippet
@@ -174,9 +189,13 @@ var PlanetArticleDetail = React.createClass({
{snippet.callSign} {snippet.updatedAt}
-
+
+
+
+
+
@@ -212,6 +231,9 @@ module.exports = React.createClass({
this.unsubscribe()
},
onFetched: function (res) {
+ var snippets = this.state.currentPlanet == null ? null : this.state.currentPlanet.Snippets
+ var snippet = res.data
+
switch (res.status) {
case 'planetFetched':
var planet = res.data
@@ -225,10 +247,7 @@ module.exports = React.createClass({
})
break
case 'snippetCreated':
- var snippet = res.data
-
if (snippet.PlanetId === this.state.currentPlanet.id) {
- var snippets = this.state.currentPlanet.Snippets
snippets.unshift(snippet)
this.setState({planet: this.state.currentPlanet}, function () {
var params = this.getParams()
@@ -236,7 +255,18 @@ module.exports = React.createClass({
this.transitionTo('snippets', params)
})
}
-
+ break
+ case 'snippetUpdated':
+ if (snippet.PlanetId === this.state.currentPlanet.id) {
+ snippets.some(function (_snippet, index) {
+ if (_snippet.id === snippet.id) {
+ snippets[index] = snippet
+ this.setState({snippets: snippets})
+ return true
+ }
+ return false
+ }.bind(this))
+ }
}
},
diff --git a/browser/main/Stores/PlanetStore.js b/browser/main/Stores/PlanetStore.js
index 53b9317e..14465a32 100644
--- a/browser/main/Stores/PlanetStore.js
+++ b/browser/main/Stores/PlanetStore.js
@@ -8,6 +8,7 @@ var PlanetStore = Reflux.createStore({
init: function () {
this.listenTo(PlanetActions.fetchPlanet, this.fetchPlanet)
this.listenTo(PlanetActions.createSnippet, this.createSnippet)
+ this.listenTo(PlanetActions.updateSnippet, this.updateSnippet)
},
fetchPlanet: function (planetName) {
request
@@ -47,6 +48,27 @@ var PlanetStore = Reflux.createStore({
data: res.body
})
}.bind(this))
+ },
+ updateSnippet: function (id, input) {
+ request
+ .put('http://localhost:8000/snippets/id/' + id)
+ .set({
+ Authorization: 'Bearer ' + localStorage.getItem('token')
+ })
+ .send(input)
+ .end(function (err, res) {
+ if (err) {
+ console.error(err)
+ this.trigger(null)
+ return
+ }
+
+ var snippet = res.body
+ this.trigger({
+ status: 'snippetUpdated',
+ data: snippet
+ })
+ }.bind(this))
}
})
diff --git a/browser/styles/main/containers/PlanetContainer.styl b/browser/styles/main/containers/PlanetContainer.styl
index da2b7b41..0f080cf2 100644
--- a/browser/styles/main/containers/PlanetContainer.styl
+++ b/browser/styles/main/containers/PlanetContainer.styl
@@ -129,6 +129,7 @@
overflow-y auto
li
.snippetItem
+ user-select none
border solid 2px transparent
padding 10px
cursor pointer
@@ -155,7 +156,7 @@
absolute right bottom
top 65px
left 450px
- .viewer-header
+ &>.viewer-header
height 44px
line-height 44px
padding 0 15px
diff --git a/browser/styles/main/index.styl b/browser/styles/main/index.styl
index 9449be81..93dac151 100644
--- a/browser/styles/main/index.styl
+++ b/browser/styles/main/index.styl
@@ -38,7 +38,7 @@ button
text-align center
.form-group
- margin-bottom 20px
+ margin-bottom 15px
&>label
display block
margin-bottom 5px
diff --git a/browser/styles/shared/modal.styl b/browser/styles/shared/modal.styl
index 42b0c7c3..89bd4310 100644
--- a/browser/styles/shared/modal.styl
+++ b/browser/styles/shared/modal.styl
@@ -4,6 +4,7 @@
overflow-y auto
overflow-x auto
background-color modalBaseColor
+ line-height 100%
&.hide
display none
.modal
@@ -14,6 +15,12 @@
border-radius 10px
padding 15px
box-shadow popupShadow
+ .modal-header
+ border-bottom solid 1px borderColor
+ margin-bottom 15px
+ h1
+ padding: 10px 0 15px;
+ font-size: 1.5em;
.modal-footer
clearfix()
border-top solid 1px borderColor
@@ -24,6 +31,7 @@
.launch-modal
.modal-tab
text-align center
+ margin-bottom 15px
.btn-primary, .btn-default
margin 0
border-radius 0
@@ -37,17 +45,17 @@
border-left none
border-top-right-radius 10px
border-bottom-right-radius 10px
- textarea.snippetDescription
- height 75px
- .Select
+ textarea.snippetDescription
+ height 75px
+ .Select
+ .Select-control
+ border-color borderColor
+ &.is-focused
.Select-control
- border-color borderColor
- &.is-focused
- .Select-control
- border-color brandBorderColor
- .Select-menu-outer
- border-color borderColor
- .ace_editor
- height 250px
- border-radius 5px
- border solid 1px borderColor
+ border-color brandBorderColor
+ .Select-menu-outer
+ border-color borderColor
+ .ace_editor
+ height 250px
+ border-radius 5px
+ border solid 1px borderColor