Support for plugin panels embedded into dashboards

This commit is contained in:
Fabio Manganiello 2020-12-17 02:09:23 +01:00
parent 1726cbd96a
commit bc3e0b8634
2 changed files with 70 additions and 13 deletions

View file

@ -24,15 +24,12 @@
<div class="row view-selector"> <div class="row view-selector">
<button :class="{selected: selectedView === 'lights'}" title="Lights" @click="selectedView = 'lights'"> <button :class="{selected: selectedView === 'lights'}" title="Lights" @click="selectedView = 'lights'">
<i class="icon fas fa-lightbulb" /> <i class="icon fas fa-lightbulb" />
<span class="view-title">&nbsp; Lights</span>
</button> </button>
<button :class="{selected: selectedView === 'scenes'}" title="Scenes" @click="selectedView = 'scenes'"> <button :class="{selected: selectedView === 'scenes'}" title="Scenes" @click="selectedView = 'scenes'">
<i class="icon far fa-image" /> <i class="icon far fa-image" />
<span class="view-title">&nbsp; Scenes</span>
</button> </button>
<button :class="{selected: selectedView === 'animate'}" title="Animate" @click="selectedView = 'animate'"> <button :class="{selected: selectedView === 'animate'}" title="Animate" @click="selectedView = 'animate'">
<i class="icon fas fa-video" /> <i class="icon fas fa-video" />
<span class="view-title">&nbsp; Animate</span>
</button> </button>
</div> </div>
@ -235,16 +232,10 @@ export default {
} }
} }
@media screen and (max-width: $tablet) { .icon {
.view-title { width: 100%;
display: none; text-align: center;
} font-size: 1.2em;
.icon {
width: 100%;
text-align: center;
font-size: 1.2em;
}
} }
} }
} }

View file

@ -0,0 +1,66 @@
<template>
<div class="plugin">
<Loading v-if="loading" />
<component :is="component" :config="config" v-else-if="component" />
</div>
</template>
<script>
import Utils from "@/Utils";
import Loading from "@/components/Loading";
import {defineAsyncComponent} from "vue";
export default {
name: "Plugin",
components: {Loading},
mixins: [Utils],
props: {
// Name of the plugin view to be loaded
pluginName: {
type: String,
required: true,
},
},
data() {
return {
loading: false,
component: null,
config: {},
}
},
computed: {
componentName() {
return this.pluginName.split('.').map((t) => t[0].toUpperCase() + t.slice(1)).join('')
},
},
methods: {
refresh: async function() {
this.loading = true
try {
this.component = defineAsyncComponent(() => import(`@/components/panels/${this.componentName}/Index`))
this.$options.components[this.componentName] = this.component
this.config = (await this.request('config.get_plugins'))?.[this.pluginName] || {}
} finally {
this.loading = false
}
},
},
mounted: function() {
this.refresh()
},
}
</script>
<style lang="scss" scoped>
.plugin {
margin: -1em 0 0 -1em !important;
padding: 0;
width: calc(100% + 2em);
height: calc(100% + 2em);
}
</style>