Skip to content

Commit

Permalink
feat: Adds flash message for save and errors
Browse files Browse the repository at this point in the history
  • Loading branch information
cadriel committed Sep 30, 2020
1 parent 7b05b82 commit 874d6e7
Show file tree
Hide file tree
Showing 10 changed files with 239 additions and 141 deletions.
171 changes: 33 additions & 138 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,115 +1,17 @@
<template>
<v-app>
<!-- <v-navigation-drawer
v-model="drawer"
app
clipped
>
<v-list dense>
<v-list-item link to="/">
<v-list-item-action>
<v-icon>mdi-view-dashboard</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>Dashboard</v-list-item-title>
</v-list-item-content>
</v-list-item>
<app-bar></app-bar>

<v-list-item link to="/settings">
<v-list-item-action>
<v-icon>mdi-cog</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>Settings</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-item link to="/about">
<v-list-item-action>
<v-icon>mdi-cog</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>About</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer> -->

<v-app-bar
app
clipped-left
>
<!-- <v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon> -->
<!-- <img src="./assets/logo.svg" class="logo" /> -->
<v-icon large color="#1970b5">mdi-printer-3d-nozzle</v-icon>
<v-toolbar-title class="title text-h4">
Fluidd
</v-toolbar-title>
<v-spacer />
<v-btn color="secondary" class="mr-2" to="/"><v-icon small class="mr-2">mdi-home</v-icon> Dashboard</v-btn>
<!-- <v-btn color="secondary" class="mr-2" to="/configuration"><v-icon small class="mr-2">mdi-tune</v-icon> Configuration</v-btn> -->
<v-spacer />
<v-tooltip bottom v-if="printerConnected && klippyConnected">
<template v-slot:activator="{ on, attrs }">
<v-btn @click="emergencyStop()" v-bind="attrs" v-on="on" icon color="error"><v-icon>mdi-car-brake-alert</v-icon></v-btn>
</template>
Emergency Stop
</v-tooltip>
<v-btn icon color="white" class="mr-2" to="/settings"><v-icon small>mdi-cog</v-icon></v-btn>
<!-- <v-menu bottom :offset-y="true" v-if="printerConnected && klippyConnected">
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs" v-on="on" icon color="white"><v-icon>mdi-dots-vertical</v-icon></v-btn>
</template>
<v-list nav dense transition="slide-y-transition" width="250">
<v-list-item to="/">
<v-list-item-icon>
<v-icon>mdi-home</v-icon>
</v-list-item-icon>
<v-list-item-title>Home</v-list-item-title>
</v-list-item>
<v-list-item to="/configuration">
<v-list-item-icon>
<v-icon>mdi-cog</v-icon>
</v-list-item-icon>
<v-list-item-title>Configuration</v-list-item-title>
</v-list-item>
</v-list>
</v-menu> -->
<!-- <v-btn icon color="white" to="/settings"><v-icon>mdi-dots-vertical</v-icon></v-btn> -->
</v-app-bar>
<FlashMessage
v-model="flashMessage.open"
:text="flashMessage.text"
:type="flashMessage.type"
:timeout="flashMessage.timeout"
/>

<v-main>
<router-view v-if="printerConnected && klippyConnected" />
<v-container style="height: 400px;" v-if="!printerConnected || !klippyConnected">
<v-row
class="fill-height"
align-content="center"
justify="center"
>
<v-col
class="subtitle-1 text-center"
cols="12"
v-if="!printerConnected"
>
Connecting to printer...
</v-col>
<v-col cols="6" v-if="!klippyConnected">
<v-alert type="error" v-if="!klippyConnected">
Klippy has disconnected or is shutdown.<br />
<span v-html=klippyError></span>
</v-alert>
<v-btn block color="warning" @click="sendGcode('FIRMWARE_RESTART')" class="me-2 mb-2">Firmware Restart</v-btn>
</v-col>
<v-col cols="6" v-if="!printerConnected">
<v-progress-linear
color="warning"
indeterminate
rounded
height="6"
></v-progress-linear>
</v-col>
</v-row>
</v-container>
<app-disconnected v-if="!printerConnected || !klippyConnected"></app-disconnected>
</v-main>

<v-footer app>
Expand All @@ -119,14 +21,28 @@
</template>

<script lang="ts">
import { Component, Mixins, Watch } from 'vue-property-decorator'
import { Component, Mixins } from 'vue-property-decorator'
import EventBus from '@/eventBus'
import UtilsMixin from './mixins/utils'
import { SocketActions } from './socketActions'
import { FlashMessage as FlashMessageType } from '@/types'
import AppBar from '@/components/AppBar.vue'
import AppDisconnected from '@/components/AppDisconnected.vue'
import FlashMessage from '@/components/FlashMessage.vue'
@Component({
components: {}
components: {
AppBar,
AppDisconnected,
FlashMessage
}
})
export default class App extends Mixins(UtilsMixin) {
flashMessage: FlashMessageType = {
open: false,
text: undefined,
type: undefined
}
get printerConnected () {
return this.$store.getters['socket/getConnectionState']
}
Expand All @@ -135,42 +51,21 @@ export default class App extends Mixins(UtilsMixin) {
return this.$store.state.socket.printer.info.state
}
get klippyError () {
const message = this.$store.state.socket.printer.info.state_message
if (message) {
return message.replace(/(?:\r\n|\r|\n)/g, '<br />')
}
return ''
}
get klippyConnected () {
if (this.klippyState !== 'ready') {
return false
}
return true
}
get currentFile () {
return this.$store.state.socket.printer.print_stats.filename
}
get unsavedChanges () {
return this.$store.state.config.unsavedChanges
}
@Watch('currentFile')
onCurrentFileChanged (val: string) {
if (val && val.length > 0) {
SocketActions.serverFilesMetaData(val)
}
}
emergencyStop () {
SocketActions.printerEmergencyStop()
}
created () {
this.$vuetify.theme.dark = true
mounted () {
this.$vuetify.theme.dark = this.$store.state.darkMode
EventBus.$on('flashMessage', (payload: FlashMessageType) => {
this.flashMessage.text = (payload && payload.text) || undefined
this.flashMessage.type = (payload && payload.type) || undefined
this.flashMessage.timeout = (payload && payload.timeout !== undefined) ? payload.timeout : undefined
this.flashMessage.open = true
})
}
}
</script>
Expand Down
76 changes: 76 additions & 0 deletions src/components/AppBar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<template>
<v-app-bar
app
clipped-left
>
<!-- <v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon> -->
<!-- <img src="./assets/logo.svg" class="logo" /> -->
<v-icon large color="#1970b5">mdi-printer-3d-nozzle</v-icon>
<v-toolbar-title class="title text-h4">
Fluidd
</v-toolbar-title>
<v-spacer />
<v-btn color="secondary" class="mr-2" to="/"><v-icon small class="mr-2">mdi-home</v-icon> Dashboard</v-btn>
<!-- <v-btn color="secondary" class="mr-2" to="/configuration"><v-icon small class="mr-2">mdi-tune</v-icon> Configuration</v-btn> -->
<v-spacer />
<v-tooltip bottom v-if="printerConnected && klippyConnected">
<template v-slot:activator="{ on, attrs }">
<v-btn @click="emergencyStop()" v-bind="attrs" v-on="on" icon color="error"><v-icon>mdi-car-brake-alert</v-icon></v-btn>
</template>
Emergency Stop
</v-tooltip>
<v-btn icon color="white" class="mr-2" to="/settings"><v-icon small>mdi-cog</v-icon></v-btn>
</v-app-bar>
</template>

<script lang="ts">
import { Component, Mixins, Watch } from 'vue-property-decorator'
import UtilsMixin from '@/mixins/utils'
import { SocketActions } from '@/socketActions'
@Component({
components: {}
})
export default class AppBar extends Mixins(UtilsMixin) {
get printerConnected () {
return this.$store.getters['socket/getConnectionState']
}
get klippyState () {
return this.$store.state.socket.printer.info.state
}
get klippyConnected () {
if (this.klippyState !== 'ready') {
return false
}
return true
}
get currentFile () {
return this.$store.state.socket.printer.print_stats.filename
}
// Watch currentfile and refresh its metadata to ensure
// our status has the correct data.
@Watch('currentFile')
oncurrentFileChanged (val: string) {
if (val && val.length > 0) {
SocketActions.serverFilesMetaData(val)
}
}
}
</script>

<style lang="scss" scoped>
.title {
background: -webkit-linear-gradient(45deg, #1970b5, #9accf5);
background-clip: text;
-webkit-text-fill-color: transparent;}
.logo {
margin-right: 12px;
max-height: 40px;
max-width: 40px;
object-fit: contain;
}
</style>
65 changes: 65 additions & 0 deletions src/components/AppDisconnected.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<template>
<v-container style="height: 400px;">
<v-row
class="fill-height"
align-content="center"
justify="center"
>
<v-col
class="subtitle-1 text-center"
cols="12"
v-if="!printerConnected"
>
Connecting to printer...
</v-col>
<v-col cols="6" v-if="!klippyConnected">
<v-alert type="error" v-if="!klippyConnected">
Klippy has disconnected or is shutdown.<br />
<span v-html=klippyError></span>
</v-alert>
<v-btn block color="warning" @click="sendGcode('FIRMWARE_RESTART')" class="me-2 mb-2">Firmware Restart</v-btn>
</v-col>
<v-col cols="6" v-if="!printerConnected">
<v-progress-linear
color="warning"
indeterminate
rounded
height="6"
></v-progress-linear>
</v-col>
</v-row>
</v-container>
</template>

<script lang="ts">
import { Component, Mixins } from 'vue-property-decorator'
import UtilsMixin from '@/mixins/utils'
@Component({
components: {}
})
export default class AppDisconnected extends Mixins(UtilsMixin) {
get printerConnected () {
return this.$store.getters['socket/getConnectionState']
}
get klippyState () {
return this.$store.state.socket.printer.info.state
}
get klippyConnected () {
if (this.klippyState !== 'ready') {
return false
}
return true
}
get klippyError () {
const message = this.$store.state.socket.printer.info.state_message
if (message) {
return message.replace(/(?:\r\n|\r|\n)/g, '<br />')
}
return ''
}
}
</script>
49 changes: 49 additions & 0 deletions src/components/FlashMessage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<template>
<v-snackbar
v-model="open"
:color="type"
:timeout="timeout"
top
>
{{ text }}

<template v-slot:action="{ attrs }">
<v-btn
dark
text
v-bind="attrs"
@click="open = false"
>
Close
</v-btn>
</template>
</v-snackbar>
</template>

<script lang="ts">
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
@Component({})
export default class FlashMessage extends Vue {
@Prop({ type: Boolean })
value!: boolean;
@Prop({ type: String, default: 'success' })
type!: string;
@Prop({ type: String, default: 'Saved!' })
text!: string;
@Prop({ type: Number, default: 4000 })
timeout!: number;
get open () {
return this.$props.value
}
set open (value: boolean) {
this.$emit('input', value)
}
}
</script>
Loading

0 comments on commit 874d6e7

Please sign in to comment.