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" />
|
<EntityIcon :entity="value" :loading="loading" :error="error" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="label col-6">
|
<div class="label col-5">
|
||||||
<div class="name" v-text="value.name" />
|
<div class="name" v-text="value.name" />
|
||||||
</div>
|
</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-if="!value.enabled">Disabled</div>
|
||||||
<div class="value" v-else-if="isRunning">Running</div>
|
<div class="value" v-else-if="isRunning">Running</div>
|
||||||
<div class="value" v-else-if="isSnoozed">Snoozed</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="body children" v-if="!collapsed" @click.stop="prevent">
|
||||||
<div class="child">
|
<div class="child">
|
||||||
<label :for="enableInputId" class="label">
|
<label :for="enableInputId" class="label">
|
||||||
<div class="name col-s-12 col-m-6">Enabled</div>
|
<div class="name col-6">Enabled</div>
|
||||||
<div class="value col-s-12 col-m-6">
|
<div class="value col-6">
|
||||||
<ToggleSwitch :id="enableInputId" :value="value.enabled" @input="setEnabled" />
|
<ToggleSwitch :id="enableInputId" :value="value.enabled" @input="setEnabled" />
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="child buttons" v-if="isRunning || isSnoozed">
|
<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">
|
<div class="value">
|
||||||
<button class="btn btn-default" @click="snooze">Snooze</button>
|
<button class="btn btn-default" @click="snooze">Snooze</button>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label :for="dismissInputId" class="label col-s-12"
|
<label :for="dismissInputId" class="label"
|
||||||
:class="{'col-m-6': isRunning, 'col-m-12': isSnoozed}">
|
:class="{'col-6': isRunning, 'col-12': !isRunning}">
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<button class="btn btn-default" @click="dismiss">Dismiss</button>
|
<button class="btn btn-default" @click="dismiss">Dismiss</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -107,7 +107,7 @@ export default {
|
||||||
await this.request(
|
await this.request(
|
||||||
'alarm.set_enabled',
|
'alarm.set_enabled',
|
||||||
{
|
{
|
||||||
name: this.value.name,
|
name: this.value.external_id,
|
||||||
enabled: !this.value.enabled,
|
enabled: !this.value.enabled,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -138,6 +138,31 @@ export default {
|
||||||
e.stopPropagation()
|
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>
|
</script>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue