Skip to content

Commit

Permalink
Merge pull request #138 from jemu75/dev-v4
Browse files Browse the repository at this point in the history
v4.6.0
  • Loading branch information
jemu75 authored Dec 21, 2024
2 parents 27974fd + 6d09a9d commit c378fd2
Show file tree
Hide file tree
Showing 21 changed files with 276 additions and 197 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,18 @@ Panels können ausgeklappt werden sobald mehr als eine aktive Ebene im Bereich [
|expandable|false|soll ausklappbar sein [boolean]|
|expanded|false|ist beim Laden ausgeklappt [boolean]|
|maximizable|false|kann auf volle Bildschirmgröße maximiert werden [boolean]|

## Element popout
Panels können als Popup angezeigt werden, sobald ein FHEM Reading einen bestimmten Wert hat. Beim Schließen des Popup kann optional ein FHEM Kommando gesendet werden.

|Parameter|Default|Beschreibung|
|---|---|---|
|reading||siehe Parameter [reading](#konfiguration-der-elemente)|
|value||siehe Parameter [value](#konfiguration-der-elemente)|
|show|false|soll ausklappbar sein [boolean]|
|width|400px|legt die Breite des Popup in 'px' oder '%' fest [string]|
|cmd|| FHEM Kommando [string]|

### Element sortby
Panels können in einer bestimmten Reihenfolge angezeigt werden. Hierfür kann ein beliebiger Sortierschlüssel festgelegt werden. Panels mit Sortierschlüssel werden immer zuerst angezeigt. Danach folgen alle Panels ohne Sortierschlüssel.

Expand Down
4 changes: 4 additions & 0 deletions public/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# v.4.6.0 (21.12.2024)
## Panel
- new panel element popout
- bugfix position of vertical divider
# v4.5.3 (12.12.2024)
## App
- bugfix for panel width on large screens
Expand Down
16 changes: 16 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import router from '@/router'
import AppNavigation from './components/AppNavigation.vue'
import OptionsMenu from './components/OptionsMenu.vue'
import PanelCard from './components/PanelCard.vue'
import logo from '@/assets/logo_v4.png'
const fhem = useFhemStore()
Expand Down Expand Up @@ -107,6 +108,21 @@
@click:close="fhem.app.message = false"
>
</v-alert>

<template v-if="fhem.app.popOutList.length > 0 && !/=maximized$/.test(fhem.app.currentView)">
<v-dialog
v-model="fhem.app.popOutList[0].show"
:width="fhem.app.popOutList[0].width"
opacity="60%"
persistent
class="noselect"
>
<v-sheet>
<PanelCard :panel="fhem.app.panelList[fhem.app.popOutList[0].panel]" :popoutIdx="0"/>
</v-sheet>
</v-dialog>
</template>

<RouterView />
</v-container>
</v-main>
Expand Down
21 changes: 19 additions & 2 deletions src/components/PanelCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import PanelMain from './PanelMain.vue'
const item = defineProps({
panel: Object
panel: Object,
popoutIdx: { type: Number, default: -1 }
})
const fhem = useFhemStore()
Expand Down Expand Up @@ -150,6 +151,22 @@
window.open(fhem.createURL('?detail=' + device), '_self')
}
function closePopout() {
let cmd = fhem.handleDefs(item.panel.panel.popout, ['show', 'width', 'cmd'], [true, null, null]).cmd
let cmdList
if(cmd) {
cmdList = cmd.split(';')
for(const [idx] of Object.entries(cmdList)) {
for(const device of item.panel.panel.devices) cmdList[idx] = cmdList[idx].replace(' ' + device.split(':')[0] + ' ', ' ' + device.split(':')[1] + ' ')
}
fhem.request('text', cmdList.join(';'))
}
fhem.app.popOutList.splice(item.popoutIdx, 1)
}
function getInfo(pos) {
let res = fhem.handleDefs(item.panel.info[pos], ['text', 'icon', 'color'],['', '', ''])
Expand Down Expand Up @@ -201,7 +218,6 @@
<v-img :src="img.url" :gradient="img.url ? fhem.app.header.imageGradient : ''" height="48" cover>
<v-toolbar color="transparent" density="compact" class="pr-1">
<v-toolbar-title class="text-truncate">{{ title.title }}</v-toolbar-title>

<template v-slot:append>
<div v-if="fhem.app.settings.loglevel > 6">
{{ sortby.sortby }}
Expand Down Expand Up @@ -234,6 +250,7 @@
</v-menu>
</div>
<v-btn v-if="lvl.icon" :icon="lvl.icon" size="small" variant="plain" density="compact" @click="lvl.isClick = true"></v-btn>
<v-btn v-if="popoutIdx !== -1" icon="mdi-close" size="small" variant="plain" @click="closePopout"></v-btn>
</template>
</v-toolbar>
</v-img>
Expand Down
10 changes: 1 addition & 9 deletions src/components/PanelMain.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,6 @@
return fhem.handleDefs(lvl[position].size, ['size'],[false]).size
}
function getClass(position) {
let res = ''
if(['info'].indexOf(position) !== -1) res = "mx-2"
return res
}
function showDivider(lvl, position) {
return lvl[position] ? fhem.handleDefs(lvl[position].divider, ['show'],[false]).show : false
}
Expand Down Expand Up @@ -58,7 +50,7 @@
<v-row v-if="levels.indexOf(idx) !== -1 ? true : false" no-gutters class="text-center align-center">
<v-sheet :height="getHeight(lvl, 'level')"></v-sheet>
<template v-for="position of ['left1', 'left2', 'mid', 'right1', 'right2']" :key="position">
<v-col v-if="lvl.level[position]" :cols="getCols(lvl, position)" :class="getClass(lvl.level[position])">
<v-col v-if="lvl.level[position]" :cols="getCols(lvl, position)">
<component :is="getComponent(lvl.level[position])" :el="lvl[position]" :iconmap="iconmap" :devices="devices" :height="getHeight(lvl, 'level')"></component>
</v-col>
<v-divider v-if="showDivider(lvl, position)" vertical></v-divider>
Expand Down
54 changes: 28 additions & 26 deletions src/components/PanelMainInfo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,35 +41,37 @@
</script>

<template>
<div v-if="el.text" :class="text.format">
{{ text.text }}
</div>
<div class="mx-2">
<div v-if="el.text" :class="text.format">
{{ text.text }}
</div>

<v-icon v-if="el.icon" :color="icon.color" :size="icon.size">
{{ icon.icon }}
</v-icon>
<v-icon v-if="el.icon" :color="icon.color" :size="icon.size">
{{ icon.icon }}
</v-icon>

<v-progress-circular v-if="el.status && !status.linear"
width="4"
v-model="status.level"
:color="status.color"
:reverse="status.reverse">
</v-progress-circular>
<v-progress-circular v-if="el.status && !status.linear"
width="4"
v-model="status.level"
:color="status.color"
:reverse="status.reverse">
</v-progress-circular>

<v-progress-linear v-if="el.status && status.linear"
height="7"
rounded
v-model="status.level"
:color="status.color"
:reverse="status.reverse">
</v-progress-linear>
<v-progress-linear v-if="el.status && status.linear"
height="7"
rounded
v-model="status.level"
:color="status.color"
:reverse="status.reverse">
</v-progress-linear>

<div :class="el.text2 ? text2.format : text3.format">
<span v-if="el.text2" :class="text2.format">
{{ text2.text }}
</span>
<span v-if="el.text3" :class="text3.format">
{{ text3.text }}
</span>
<div :class="el.text2 ? text2.format : text3.format">
<span v-if="el.text2" :class="text2.format">
{{ text2.text }}
</span>
<span v-if="el.text3" :class="text3.format">
{{ text3.text }}
</span>
</div>
</div>
</template>
1 change: 1 addition & 0 deletions src/components/SettingsPropsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
{ type: 'defs', show: ['templates'], required: true, prop: 'devicekeys', def: 'key:description', help: 'element-devicekeys' },
{ type: 'defs', show: ['extended.panels', 'templates'], required: false, prop: 'navigation', def: 'reading:value:route', help: 'element-navigation', assist: 'props' },
{ type: 'defs', show: ['extended.panels', 'templates'], required: false, prop: 'expandable', def: 'reading:value:expandable:expanded:maximizable', help: 'element-expandable', assist: 'props' },
{ type: 'defs', show: ['extended.panels', 'templates'], required: false, prop: 'popout', def: 'reading:value:show:width:cmd', help: 'element-popout', assist: 'props' },
{ type: 'defs', show: ['extended.panels', 'templates'], required: false, prop: 'sortby', def: 'reading:value:sortkey', help: 'element-sortkey', assist: 'props' },
{ type: 'defs', show: ['extended.panels', 'templates'], required: false, prop: 'show', def: 'reading:value:show', help: 'element-show', assist: 'props' },
{ type: 'defs', show: ['extended.panels', 'templates'], required: false, prop: 'iconmap', def: 'search:icon', help: 'element-iconmap' }
Expand Down
66 changes: 50 additions & 16 deletions src/stores/fhem.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export const useFhemStore = defineStore('fhem', () => {
fhemDevice: null,
panelView: [],
panelList: [],
popOutList: [],
navigation: [],
threads: [],
distTemplates: [
Expand Down Expand Up @@ -448,12 +449,30 @@ export const useFhemStore = defineStore('fhem', () => {
request('text', 'set ' + app.fhemDevice + ' update')
}

//coreFunction handle internal Task PopOut-Event
function handlePopOut(panels, val) {
let panelIdx,
popoutDef

for(const idx of panels) {
panelIdx = app.popOutList.map((e) => e.panel).indexOf(idx)
popoutDef = handleDefs(app.panelList[idx].panel.popout, ['show', 'width', 'cmd'], [false, '400px', null])
popoutDef.panel = idx

if(panelIdx === -1 && popoutDef.show) app.popOutList.push(popoutDef)
if(panelIdx !== -1 && popoutDef.show) app.popOutList[panelIdx] = popoutDef
if(panelIdx !== -1 && !popoutDef.show) app.popOutList.splice(panelIdx, 1)
}
}

//subFunction for handle internal tasks triggered from FHEM (update, darkMode) called from handleEventBuffer and initialLoad
function handleInternalTask(task, val) {
if(task === 'update' && val === '1') app.updateAvailable = true
if(task === 'update' && val === '0' && app.updateProgress) location.reload()
function handleInternalTask(obj, val) {
if(obj.task === 'update' && val === '1') app.updateAvailable = true
if(obj.task === 'update' && val === '0' && app.updateProgress) location.reload()

if(obj.task === 'darkMode') changeDarkMode(handleDefs([[app.header.darkModeOverFhem.split(':')[1], val, 'true'].join(':')], ['dark'], [false]).dark ? 'dark' : 'light')

if(task === 'darkMode') changeDarkMode(handleDefs([[app.header.darkModeOverFhem.split(':')[1], val, 'true'].join(':')], ['dark'], [false]).dark ? 'dark' : 'light')
if(obj.task === 'popout') handlePopOut(obj.popoutPanels, val)
}

//subFunction for update values in panelList
Expand Down Expand Up @@ -487,7 +506,7 @@ export const useFhemStore = defineStore('fhem', () => {
}

if(stat.panelMap[idx].task) {
handleInternalTask(stat.panelMap[idx].task, evt.value)
handleInternalTask(stat.panelMap[idx], evt.value)
}

if(!localLoop) log(6, 'Data from FHEM handled.', evt)
Expand Down Expand Up @@ -607,7 +626,8 @@ export const useFhemStore = defineStore('fhem', () => {
function createPanelMap(devices, obj, path) {
let val,
reading,
idx
idx,
item

if(obj) {
for (const [key, value] of Object.entries(obj)) {
Expand All @@ -622,9 +642,22 @@ export const useFhemStore = defineStore('fhem', () => {
idx = stat.panelMap.map((e) => e.reading).indexOf(reading)

if(idx === -1) {
stat.panelMap.push({ reading: reading, items: [[...path, key]] })
item = { reading: reading, items: [[...path, key]] }
if(path.slice(-2).join('-') === 'panel-popout') {
item.task = 'popout'
item.popoutPanels = [path[0]]
}
stat.panelMap.push(item)
} else {
stat.panelMap[idx].items.push([...path, key])
if(path.slice(-2).join('-') === 'panel-popout') {
if(stat.panelMap[idx].task === 'popout' && !stat.panelMap[idx].popoutPanels.find((e) => e === path[0])) {
stat.panelMap[idx].popoutPanels.push(path[0])
} else {
stat.panelMap[idx].task = 'popout'
stat.panelMap[idx].popoutPanels = [path[0]]
}
}
}

if(/%d\(.*{.*"diff".*/.test(val)) {
Expand Down Expand Up @@ -710,14 +743,15 @@ export const useFhemStore = defineStore('fhem', () => {
}
}

//add watching for updates
//add updatewatcher
taskIdx = stat.panelMap.map((e) => e.reading).indexOf(app.fhemDevice + '-update_available')
if(taskIdx !== -1) {
stat.panelMap[taskIdx].task = 'update'
} else {
stat.panelMap.push({ reading: app.fhemDevice + '-update_available', task: 'update' })
}

//add darkmodewatcher
if(app.header.darkModeOverFhem) {
darkModeDef = app.header.darkModeOverFhem.split(':')
if(darkModeDef.length === 2) {
Expand Down Expand Up @@ -748,7 +782,8 @@ export const useFhemStore = defineStore('fhem', () => {
parts,
idx,
jsonList2Item,
val
val,
taskList = []

for(const item of stat.panelMap) {
device = item.reading.split('-')[0]
Expand All @@ -764,7 +799,7 @@ export const useFhemStore = defineStore('fhem', () => {
res = await request('json', 'jsonlist2 ' + deviceList.join(','))
if(!res) return

for(const item of stat.panelMap) {
for(const [mapIdx, item] of stat.panelMap.entries()) {
parts = item.reading.split('-')
idx = res.Results.map((e) => e.Name).indexOf(parts[0])

Expand All @@ -786,16 +821,15 @@ export const useFhemStore = defineStore('fhem', () => {

val = getEl(res.Results[idx], jsonList2Item)

if(item.items) {
for(const path of item.items) doUpdate(panelList, path, val)
}
if(item.items) for(const path of item.items) doUpdate(panelList, path, val)

if(item.task) {
handleInternalTask(item.task, val)
}
if(item.task) taskList.push({ idx: mapIdx, value: val })
}

app.panelList = panelList

for(const item of taskList) handleInternalTask(stat.panelMap[item.idx], item.value)

log(4, 'Devices from FHEM loaded.', res)
return true
}
Expand Down
1 change: 0 additions & 1 deletion src/views/DevicesView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import { computed } from 'vue'
import { useFhemStore } from '@/stores/fhem'
import PanelCard from '../components/PanelCard.vue'
const fhem = useFhemStore()
Expand Down
4 changes: 4 additions & 0 deletions www/fhemapp4/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# v.4.6.0 (21.12.2024)
## Panel
- new panel element popout
- bugfix position of vertical divider
# v4.5.3 (12.12.2024)
## App
- bugfix for panel width on large screens
Expand Down
1 change: 1 addition & 0 deletions www/fhemapp4/assets/DevicesView-CzwCxc1m.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion www/fhemapp4/assets/DevicesView-FLfiMKGY.js

This file was deleted.

Loading

0 comments on commit c378fd2

Please sign in to comment.