See #262: light messaging area and helpers for the front-end

merge-requests/251/head
Eliot Berriot 2018-06-07 12:59:22 +02:00
rodzic 4c81de9226
commit 3634c00ee6
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: DD6965E2476E5C27
6 zmienionych plików z 167 dodań i 2 usunięć

Wyświetl plik

@ -1,6 +1,7 @@
<template>
<div id="app">
<sidebar></sidebar>
<service-messages v-if="messages.length > 0" />
<router-view :key="$route.fullPath"></router-view>
<div class="ui fitted divider"></div>
<div id="footer" class="ui vertical footer segment">
@ -44,9 +45,11 @@
<script>
import axios from 'axios'
import _ from 'lodash'
import {mapState} from 'vuex'
import Sidebar from '@/components/Sidebar'
import Raven from '@/components/Raven'
import ServiceMessages from '@/components/ServiceMessages'
import PlaylistModal from '@/components/playlists/PlaylistModal'
@ -55,7 +58,8 @@ export default {
components: {
Sidebar,
Raven,
PlaylistModal
PlaylistModal,
ServiceMessages
},
data () {
return {
@ -80,6 +84,9 @@ export default {
}
},
computed: {
...mapState({
messages: state => state.ui.messages
}),
version () {
if (!this.nodeinfo) {
return null
@ -115,6 +122,14 @@ html, body {
}
transform: none !important;
}
.service-messages {
position: fixed;
bottom: 1em;
left: 1em;
@include media(">desktop") {
left: 350px;
}
}
.main-pusher {
padding: 1.5rem 0;
}

Wyświetl plik

@ -0,0 +1,83 @@
<template>
<div class="service-messages">
<message v-for="message in displayedMessages" :key="String(message.date)" :class="['large', getLevel(message)]">
<p>{{ message.content }}</p>
</message>
</div>
</template>
<script>
import _ from 'lodash'
import {mapState} from 'vuex'
export default {
data () {
return {
date: new Date(),
interval: null
}
},
created () {
this.setupInterval()
},
destroyed () {
if (this.interval) {
clearInterval(this.interval)
}
},
computed: {
...mapState({
messages: state => state.ui.messages,
displayDuration: state => state.ui.messageDisplayDuration
}),
displayedMessages () {
let now = this.date
let interval = this.displayDuration
let toDisplay = this.messages.filter(m => {
return now - m.date <= interval
})
return _.reverse(toDisplay).slice(0, 5)
}
},
methods: {
setupInterval () {
if (this.interval) {
return
}
let self = this
this.interval = setInterval(() => {
if (self.displayedMessages.length === 0) {
clearInterval(self.interval)
this.interval = null
}
self.date = new Date()
}, 1000)
},
getLevel (message) {
return message.level || 'blue'
}
},
watch: {
messages: {
handler (v) {
if (v.length > 0 && !this.interval) {
this.setupInterval()
}
},
deep: true
}
}
}
</script>
<style>
.service-messages {
z-index: 9999;
margin-left: 1em;
min-width: 20em;
max-width: 40em;
}
.service-messages .message:last-child {
margin-bottom: 0;
}
</style>

Wyświetl plik

@ -0,0 +1,36 @@
<template>
<div class="ui message">
<div class="content">
<slot></slot>
</div>
<i class="close icon"></i>
</div>
</template>
<script>
import $ from 'jquery'
export default {
mounted () {
let self = this
$(this.$el).find('.close.icon').on('click', function () {
$(self.$el).transition('fade', 125)
})
$(this.$el).on('click', function () {
$(self.$el).transition('fade', 125)
})
}
}
</script>
<style scoped>
.ui.message .content {
padding-right: 0.5em;
cursor: pointer;
}
.ui.message .content :first-child {
margin-top: 0;
}
.ui.message .content :last-child {
margin-bottom: 0;
}
</style>

Wyświetl plik

@ -12,4 +12,8 @@ import DangerousButton from '@/components/common/DangerousButton'
Vue.component('dangerous-button', DangerousButton)
import Message from '@/components/common/Message'
Vue.component('message', Message)
export default {}

Wyświetl plik

@ -2,11 +2,20 @@
export default {
namespaced: true,
state: {
lastDate: new Date()
lastDate: new Date(),
maxMessages: 100,
messageDisplayDuration: 10000,
messages: []
},
mutations: {
computeLastDate: (state) => {
state.lastDate = new Date()
},
addMessage (state, message) {
state.messages.push(message)
if (state.messages.length > state.maxMessages) {
state.messages.shift()
}
}
}
}

Wyświetl plik

@ -0,0 +1,18 @@
import store from '@/store/ui'
import { testAction } from '../../utils'
describe('store/ui', () => {
describe('mutations', () => {
it('addMessage', () => {
const state = {maxMessages: 100, messages: []}
store.mutations.addMessage(state, 'hello')
expect(state.messages).to.deep.equal(['hello'])
})
it('addMessage', () => {
const state = {maxMessages: 1, messages: ['hello']}
store.mutations.addMessage(state, 'world')
expect(state.messages).to.deep.equal(['world'])
})
})
})