Files
dougal-software/lib/www/client/source/src/App.vue
2025-08-20 12:03:53 +02:00

120 lines
2.6 KiB
Vue

<template>
<v-app id="dougal">
<dougal-navigation></dougal-navigation>
<v-main>
<router-view></router-view>
</v-main>
<dougal-footer></dougal-footer>
<v-snackbar v-model="snack"
:color="snackColour"
:timeout="6000"
>
<div v-html="snackText"></div>
<template v-slot:action="{ attrs }">
<v-btn
text
v-bind="attrs"
@click="snack = false"
>
Close
</v-btn>
</template>
</v-snackbar>
</v-app>
</template>
<style lang="stylus">
@import '../node_modules/typeface-roboto/index.css'
@import '../node_modules/@mdi/font/css/materialdesignicons.css'
.markdown.v-textarea textarea
font-family monospace
line-height 1.1 !important
</style>
</style>
<script>
import { mapActions, mapGetters } from 'vuex';
import DougalNavigation from './components/navigation';
import DougalFooter from './components/footer';
export default {
name: 'Dougal',
components: {
DougalNavigation,
DougalFooter
},
data: () => ({
snack: false
}),
computed: {
snackText () { return this.$root.markdownInline(this.$store.state.snack.snackText) },
snackColour () { return this.$store.state.snack.snackColour },
},
watch: {
"$vuetify.theme.dark": {
handler (newValue) {
localStorage.setItem("darkTheme", newValue);
}
},
snackText (newVal) {
this.snack = !!newVal;
},
snack (newVal) {
// When the snack is hidden (one way or another), clear
// the text so that if we receive the same message again
// afterwards it will be shown. This way, if we get spammed
// we're also not triggering the snack too often.
if (!newVal) {
this.$store.commit('setSnackText', "");
}
},
},
methods: {
handleJWT (context, {payload}) {
this.setCredentials({token: payload.token});
},
handleProject (context, {payload}) {
if (payload?.table == "public") {
this.refreshProjects();
}
},
registerNotificationHandlers () {
this.$store.dispatch('registerHandler', {
table: '.jwt',
handler: this.handleJWT
});
this.$store.dispatch('registerHandler', {
table: 'project',
handler: this.handleProject
});
},
...mapActions(["setCredentials", "refreshProjects"])
},
async mounted () {
// Local Storage values are always strings
this.$vuetify.theme.dark = localStorage.getItem("darkTheme") == "true";
this.registerNotificationHandlers();
await this.setCredentials();
this.refreshProjects();
}
};
</script>