Prettier success messages

pull/144/head
Henrique Dias 2017-07-08 14:43:08 +01:00
parent 338e73a8b2
commit bb116fe5b0
No known key found for this signature in database
GPG Key ID: 936F5EB68D786730
10 changed files with 116 additions and 52 deletions

50
api.go
View File

@ -72,7 +72,7 @@ func serveAPI(c *requestContext, w http.ResponseWriter, r *http.Request) (int, e
case "resource": case "resource":
return resourceHandler(c, w, r) return resourceHandler(c, w, r)
case "users": case "users":
if !c.us.Admin && !(r.URL.Path == "/self" && r.Method == http.MethodPut) { if !c.us.Admin && !((r.URL.Path == "/change-password" || r.URL.Path == "/change-css") && r.Method == http.MethodPut) {
return http.StatusForbidden, nil return http.StatusForbidden, nil
} }
@ -503,7 +503,7 @@ func usersPutHandler(c *requestContext, w http.ResponseWriter, r *http.Request)
sid = strings.TrimSuffix(sid, "/") sid = strings.TrimSuffix(sid, "/")
id, err := strconv.Atoi(sid) id, err := strconv.Atoi(sid)
if err != nil && sid != "self" { if err != nil && sid != "change-password" && sid != "change-css" {
return http.StatusNotFound, err return http.StatusNotFound, err
} }
@ -520,33 +520,33 @@ func usersPutHandler(c *requestContext, w http.ResponseWriter, r *http.Request)
return http.StatusBadRequest, errors.New("Invalid JSON") return http.StatusBadRequest, errors.New("Invalid JSON")
} }
if sid == "self" { if sid == "change-password" {
if u.Password != "" { if u.Password == "" {
pw, err := hashPassword(u.Password) return http.StatusBadRequest, errors.New("Password cannot be empty")
if err != nil {
return http.StatusInternalServerError, err
}
c.us.Password = pw
err = c.fm.db.UpdateField(&User{ID: c.us.ID}, "Password", pw)
if err != nil {
return http.StatusInternalServerError, err
}
return http.StatusOK, nil
} }
if u.CSS != "" { pw, err := hashPassword(u.Password)
c.us.CSS = u.CSS if err != nil {
err = c.fm.db.UpdateField(&User{ID: c.us.ID}, "CSS", u.CSS) return http.StatusInternalServerError, err
if err != nil {
return http.StatusInternalServerError, err
}
return http.StatusOK, nil
} }
return http.StatusBadRequest, errors.New("Password or CSS is missing") c.us.Password = pw
err = c.fm.db.UpdateField(&User{ID: c.us.ID}, "Password", pw)
if err != nil {
return http.StatusInternalServerError, err
}
return http.StatusOK, nil
}
if sid == "change-css" {
c.us.CSS = u.CSS
err = c.fm.db.UpdateField(&User{ID: c.us.ID}, "CSS", u.CSS)
if err != nil {
return http.StatusInternalServerError, err
}
return http.StatusOK, nil
} }
// The username and the filesystem cannot be empty. // The username and the filesystem cannot be empty.

View File

@ -66,10 +66,6 @@ export default {
watch: { watch: {
'$route': 'fetchData', '$route': 'fetchData',
'reload': function () { 'reload': function () {
this.$store.commit('setReload', false)
this.$store.commit('resetSelected')
this.$store.commit('multiple', false)
this.$store.commit('closeHovers')
this.fetchData() this.fetchData()
} }
}, },
@ -82,6 +78,12 @@ export default {
methods: { methods: {
...mapMutations([ 'setLoading' ]), ...mapMutations([ 'setLoading' ]),
fetchData () { fetchData () {
// Reset view information.
this.$store.commit('setReload', false)
this.$store.commit('resetSelected')
this.$store.commit('multiple', false)
this.$store.commit('closeHovers')
// Set loading to true and reset the error. // Set loading to true and reset the error.
this.setLoading(true) this.setLoading(true)
this.error = null this.error = null

View File

@ -3,7 +3,7 @@
<site-header></site-header> <site-header></site-header>
<sidebar></sidebar> <sidebar></sidebar>
<main> <main>
<router-view></router-view> <router-view v-on:css-updated="updateCSS"></router-view>
</main> </main>
<prompts></prompts> <prompts></prompts>
</div> </div>
@ -23,12 +23,23 @@ export default {
SiteHeader, SiteHeader,
Prompts Prompts
}, },
watch: { mounted () {
'$route': function () { this.updateCSS()
// Reset selected items and multiple selection. },
this.$store.commit('resetSelected') methods: {
this.$store.commit('multiple', false) updateCSS () {
this.$store.commit('closeHovers') let css = this.$store.state.user.css
let style = document.querySelector('style[title="user-css"]')
if (style !== undefined && style !== null) {
style.parentElement.removeChild(style)
}
style = document.createElement('style')
style.title = 'user-css'
style.type = 'text/css'
style.appendChild(document.createTextNode(css))
document.head.appendChild(style)
} }
} }
} }

View File

@ -20,7 +20,7 @@
</template> </template>
<script> <script>
import { mapState } from 'vuex' import { mapState, mapMutations } from 'vuex'
import api from '@/utils/api' import api from '@/utils/api'
export default { export default {
@ -50,6 +50,7 @@ export default {
this.css = this.user.css this.css = this.user.css
}, },
methods: { methods: {
...mapMutations([ 'showSuccess' ]),
changePassword (event) { changePassword (event) {
event.preventDefault() event.preventDefault()
@ -58,8 +59,7 @@ export default {
} }
api.updatePassword(this.password).then(() => { api.updatePassword(this.password).then(() => {
console.log('Success') this.showSuccess('Password updated!')
// TODO: show success
}).catch(e => { }).catch(e => {
this.$store.commit('showError', e) this.$store.commit('showError', e)
}) })
@ -68,8 +68,9 @@ export default {
event.preventDefault() event.preventDefault()
api.updateCSS(this.css).then(() => { api.updateCSS(this.css).then(() => {
console.log('Success') this.$store.commit('setUserCSS', this.css)
// TODO: show success this.$emit('css-updated')
this.showSuccess('Styles updated!')
}).catch(e => { }).catch(e => {
this.$store.commit('showError', e) this.$store.commit('showError', e)
}) })

View File

@ -90,7 +90,10 @@ export default {
}, },
methods: { methods: {
fetchData () { fetchData () {
if (this.$route.path === '/users/new') return if (this.$route.path === '/users/new') {
this.reset()
return
}
api.getUser(this.$route.params[0]).then(user => { api.getUser(this.$route.params[0]).then(user => {
this.id = user.ID this.id = user.ID
@ -125,6 +128,19 @@ export default {
this.$router.push({ path: '/users/new' }) this.$router.push({ path: '/users/new' })
}) })
}, },
reset () {
this.id = 0
this.admin = false
this.allowNew = false
this.allowEdit = false
this.allowCommands = false
this.password = ''
this.username = ''
this.filesystem = ''
this.rules = ''
this.css = ''
this.commands = ''
},
save (event) { save (event) {
event.preventDefault() event.preventDefault()
let user = this.parseForm() let user = this.parseForm()
@ -132,6 +148,7 @@ export default {
if (this.$route.path === '/users/new') { if (this.$route.path === '/users/new') {
api.newUser(user).then(location => { api.newUser(user).then(location => {
this.$router.push({ path: location }) this.$router.push({ path: location })
this.$store.commit('showSuccess', 'User created!')
}).catch(e => { }).catch(e => {
this.$store.commit('showError', e) this.$store.commit('showError', e)
}) })
@ -140,7 +157,7 @@ export default {
} }
api.updateUser(user).then(location => { api.updateUser(user).then(location => {
this.$router.push({ path: location }) this.$store.commit('showSuccess', 'User updated!')
}).catch(e => { }).catch(e => {
this.$store.commit('showError', e) this.$store.commit('showError', e)
}) })

View File

@ -9,6 +9,7 @@
<info v-else-if="showInfo"></info> <info v-else-if="showInfo"></info>
<move v-else-if="showMove"></move> <move v-else-if="showMove"></move>
<error v-else-if="showError"></error> <error v-else-if="showError"></error>
<success v-else-if="showSuccess"></success>
<div v-show="showOverlay" @click="resetPrompts" class="overlay"></div> <div v-show="showOverlay" @click="resetPrompts" class="overlay"></div>
</div> </div>
@ -22,6 +23,7 @@ import Rename from './Rename'
import Download from './Download' import Download from './Download'
import Move from './Move' import Move from './Move'
import Error from './Error' import Error from './Error'
import Success from './Success'
import NewFile from './NewFile' import NewFile from './NewFile'
import NewDir from './NewDir' import NewDir from './NewDir'
import { mapState } from 'vuex' import { mapState } from 'vuex'
@ -34,6 +36,7 @@ export default {
Rename, Rename,
Error, Error,
Download, Download,
Success,
Move, Move,
NewFile, NewFile,
NewDir, NewDir,
@ -42,6 +45,7 @@ export default {
computed: { computed: {
...mapState(['show']), ...mapState(['show']),
showError: function () { return this.show === 'error' }, showError: function () { return this.show === 'error' },
showSuccess: function () { return this.show === 'success' },
showInfo: function () { return this.show === 'info' }, showInfo: function () { return this.show === 'info' },
showHelp: function () { return this.show === 'help' }, showHelp: function () { return this.show === 'help' },
showDelete: function () { return this.show === 'delete' }, showDelete: function () { return this.show === 'delete' },

View File

@ -0,0 +1,20 @@
<template>
<div class="prompt success">
<i class="material-icons">done</i>
<h3>{{ $store.state.showMessage }}</h3>
<div>
<button @click="close" autofocus>OK</button>
</div>
</div>
</template>
<script>
export default {
name: 'success',
methods: {
close () {
this.$store.commit('closeHovers')
}
}
}
</script>

View File

@ -64,6 +64,7 @@
background-color: #e9eaeb; background-color: #e9eaeb;
} }
.prompt.success i,
.prompt.error i { .prompt.error i {
color: #F44336; color: #F44336;
display: block; display: block;
@ -72,6 +73,7 @@
font-size: 5em; font-size: 5em;
} }
.prompt.success h3,
.prompt.error h3 { .prompt.error h3 {
text-align: center; text-align: center;
} }
@ -80,6 +82,14 @@
background-color: #F44336 background-color: #F44336
} }
.prompt.success i {
color: #8BC34A;
}
.prompt.success button {
background-color: #8BC34A;
}
/* * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * *
* PROMPT - MOVE * * PROMPT - MOVE *

View File

@ -14,17 +14,16 @@ const mutations = {
}, },
showError: (state, value) => { showError: (state, value) => {
state.show = 'error' state.show = 'error'
state.showMessage = value
if (typeof value !== 'object') { },
state.showMessage = value showSuccess: (state, value) => {
return state.show = 'success'
} state.showMessage = value
state.showMessage = value.message
}, },
setLoading: (state, value) => { state.loading = value }, setLoading: (state, value) => { state.loading = value },
setReload: (state, value) => { state.reload = value }, setReload: (state, value) => { state.reload = value },
setUser: (state, value) => (state.user = value), setUser: (state, value) => (state.user = value),
setUserCSS: (state, value) => (state.user.css = value),
setJWT: (state, value) => (state.jwt = value), setJWT: (state, value) => (state.jwt = value),
multiple: (state, value) => (state.multiple = value), multiple: (state, value) => (state.multiple = value),
addSelected: (state, value) => (state.selected.push(value)), addSelected: (state, value) => (state.selected.push(value)),

View File

@ -277,7 +277,7 @@ function updateUser (user) {
function updatePassword (password) { function updatePassword (password) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let request = new window.XMLHttpRequest() let request = new window.XMLHttpRequest()
request.open('PUT', `${store.state.baseURL}/api/users/self`, true) request.open('PUT', `${store.state.baseURL}/api/users/change-password`, true)
request.setRequestHeader('Authorization', `Bearer ${store.state.jwt}`) request.setRequestHeader('Authorization', `Bearer ${store.state.jwt}`)
request.onload = () => { request.onload = () => {
@ -298,7 +298,7 @@ function updatePassword (password) {
function updateCSS (css) { function updateCSS (css) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let request = new window.XMLHttpRequest() let request = new window.XMLHttpRequest()
request.open('PUT', `${store.state.baseURL}/api/users/self`, true) request.open('PUT', `${store.state.baseURL}/api/users/change-css`, true)
request.setRequestHeader('Authorization', `Bearer ${store.state.jwt}`) request.setRequestHeader('Authorization', `Bearer ${store.state.jwt}`)
request.onload = () => { request.onload = () => {