forked from platypush/platypush
[#340] Added alarm
UI panel.
This commit is contained in:
parent
62054e83cc
commit
dfa0727289
2 changed files with 207 additions and 8 deletions
|
@ -0,0 +1,174 @@
|
|||
<template>
|
||||
<Loading v-if="loading" />
|
||||
|
||||
<NoItems v-else-if="!Object.keys(alarms).length">
|
||||
No alarms configured
|
||||
</NoItems>
|
||||
|
||||
<div class="alarms-container" v-else>
|
||||
<div class="alarms items">
|
||||
<div class="item" v-for="alarm in alarms" :key="alarm.external_id">
|
||||
<Entity :value="alarm" @show-modal="selectedAlarm = alarm.external_id" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<EntityModal
|
||||
:entity="alarms[selectedAlarm]"
|
||||
:visible="modalVisible"
|
||||
:config-values="{}"
|
||||
@close="selectedAlarm = null"
|
||||
v-if="modalVisible" />
|
||||
|
||||
<FloatingButton icon-class="fa fa-plus" text="Add Alarm"
|
||||
@click="addAlarmModalVisible = true" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Utils from "@/Utils";
|
||||
import Loading from "@/components/Loading";
|
||||
import EntityModal from "@/components/panels/Entities/Modal";
|
||||
import Entity from "@/components/panels/Entities/Entity";
|
||||
import FloatingButton from "@/components/elements/FloatingButton";
|
||||
import NoItems from "@/components/elements/NoItems";
|
||||
|
||||
export default {
|
||||
components: {Entity, EntityModal, FloatingButton, Loading, NoItems},
|
||||
mixins: [Utils],
|
||||
props: {
|
||||
pluginName: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
addAlarmModalVisible: false,
|
||||
alarms: {},
|
||||
selectedAlarm: null,
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
modalVisible() {
|
||||
return this.alarms[this.selectedAlarm] != null
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
addAlarm(alarm) {
|
||||
alarm.name = alarm?.meta?.name_override || alarm.name
|
||||
alarm.meta = {
|
||||
...alarm.meta,
|
||||
icon: {
|
||||
'class': (alarm.meta?.icon?.['class'] || 'fas fa-stopwatch'),
|
||||
},
|
||||
}
|
||||
|
||||
this.alarms[alarm.external_id] = alarm
|
||||
},
|
||||
|
||||
async refresh() {
|
||||
this.$emit('loading', true)
|
||||
try {
|
||||
(await this.request('entities.get', {plugins: [this.pluginName]})).forEach(
|
||||
entity => this.addAlarm(entity)
|
||||
)
|
||||
} finally {
|
||||
this.$emit('loading', false)
|
||||
}
|
||||
},
|
||||
|
||||
async onEntityUpdate(msg) {
|
||||
const entity = msg?.entity
|
||||
if (entity?.plugin !== this.pluginName)
|
||||
return
|
||||
|
||||
this.addAlarm(entity)
|
||||
},
|
||||
|
||||
async onEntityDelete(msg) {
|
||||
const entity = msg?.entity
|
||||
if (entity?.plugin !== this.pluginName)
|
||||
return
|
||||
|
||||
if (this.selectedAlarm === entity.external_id)
|
||||
this.selectedAlarm = null
|
||||
|
||||
if (this.alarms[entity.external_id])
|
||||
delete this.alarms[entity.external_id]
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.refresh()
|
||||
|
||||
this.subscribe(
|
||||
this.onEntityUpdate,
|
||||
'on-alarm-entity-update',
|
||||
'platypush.message.event.entities.EntityUpdateEvent'
|
||||
)
|
||||
|
||||
this.subscribe(
|
||||
this.onEntityDelete,
|
||||
'on-alarm-entity-delete',
|
||||
'platypush.message.event.entities.EntityDeleteEvent'
|
||||
)
|
||||
},
|
||||
|
||||
unmounted() {
|
||||
this.unsubscribe('on-alarm-entity-update')
|
||||
this.unsubscribe('on-alarm-entity-delete')
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.alarms-container {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
background: $default-bg-6;
|
||||
flex-grow: 1;
|
||||
overflow-y: auto;
|
||||
justify-content: center;
|
||||
|
||||
.alarms {
|
||||
@include until($tablet) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@include from($tablet) {
|
||||
width: calc(100% - 2em);
|
||||
margin-top: 1em;
|
||||
border-radius: 1em;
|
||||
}
|
||||
|
||||
max-width: 800px;
|
||||
background: $default-bg-2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: auto;
|
||||
box-shadow: $border-shadow-bottom-right;
|
||||
|
||||
:deep(.item) {
|
||||
.entity-container {
|
||||
&:first-child {
|
||||
border-top-left-radius: 1em;
|
||||
border-top-right-radius: 1em;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom-left-radius: 1em;
|
||||
border-bottom-right-radius: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -5,11 +5,11 @@
|
|||
<EntityIcon :entity="value" :loading="loading" :error="error" />
|
||||
</div>
|
||||
|
||||
<div class="label col-6">
|
||||
<div class="label col-5">
|
||||
<div class="name" v-text="value.name" />
|
||||
</div>
|
||||
|
||||
<div class="value-and-toggler col-7" @click.stop="collapsed = !collapsed">
|
||||
<div class="value-and-toggler col-8" @click.stop="collapsed = !collapsed">
|
||||
<div class="value" v-if="!value.enabled">Disabled</div>
|
||||
<div class="value" v-else-if="isRunning">Running</div>
|
||||
<div class="value" v-else-if="isSnoozed">Snoozed</div>
|
||||
|
@ -27,22 +27,22 @@
|
|||
<div class="body children" v-if="!collapsed" @click.stop="prevent">
|
||||
<div class="child">
|
||||
<label :for="enableInputId" class="label">
|
||||
<div class="name col-s-12 col-m-6">Enabled</div>
|
||||
<div class="value col-s-12 col-m-6">
|
||||
<div class="name col-6">Enabled</div>
|
||||
<div class="value col-6">
|
||||
<ToggleSwitch :id="enableInputId" :value="value.enabled" @input="setEnabled" />
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="child buttons" v-if="isRunning || isSnoozed">
|
||||
<label :for="snoozeInputId" class="label col-s-12 col-m-6" v-if="isRunning">
|
||||
<label :for="snoozeInputId" class="label col-6" v-if="isRunning">
|
||||
<div class="value">
|
||||
<button class="btn btn-default" @click="snooze">Snooze</button>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label :for="dismissInputId" class="label col-s-12"
|
||||
:class="{'col-m-6': isRunning, 'col-m-12': isSnoozed}">
|
||||
<label :for="dismissInputId" class="label"
|
||||
:class="{'col-6': isRunning, 'col-12': !isRunning}">
|
||||
<div class="value">
|
||||
<button class="btn btn-default" @click="dismiss">Dismiss</button>
|
||||
</div>
|
||||
|
@ -107,7 +107,7 @@ export default {
|
|||
await this.request(
|
||||
'alarm.set_enabled',
|
||||
{
|
||||
name: this.value.name,
|
||||
name: this.value.external_id,
|
||||
enabled: !this.value.enabled,
|
||||
}
|
||||
)
|
||||
|
@ -138,6 +138,31 @@ export default {
|
|||
e.stopPropagation()
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.$watch(
|
||||
() => this.value,
|
||||
(newValue, oldValue) => {
|
||||
if (newValue?.state !== oldValue?.state) {
|
||||
const notif = {image: {icon: 'stopwatch'}}
|
||||
switch (newValue?.state) {
|
||||
case 'RUNNING':
|
||||
notif.text = `Alarm ${newValue.name} is running`
|
||||
break
|
||||
case 'SNOOZED':
|
||||
notif.text = `Alarm ${newValue.name} has been snoozed`
|
||||
break
|
||||
case 'DISMISSED':
|
||||
notif.text = `Alarm ${newValue.name} has been dismissed`
|
||||
break
|
||||
}
|
||||
|
||||
if (notif.text)
|
||||
this.notify(notif)
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
Loading…
Reference in a new issue