properties widget somewhat working

This commit is contained in:
Jono Targett 2026-03-16 07:22:42 +10:30
parent c33245c317
commit 566f02ede4
2 changed files with 49 additions and 27 deletions

View File

@ -13,13 +13,13 @@ import PropertiesWidget from "./components/dashboard/PropertiesWidget.vue";
<div class="layout-container">
<AppTopbar />
<div class="layout-grid">
<PropertiesWidget />
<PropertiesWidget device-id="example-gps-fedora" />
<StatsWidget />
<div class="layout-grid-row">
<!-- <div class="layout-grid-row">
<SalesTrendWidget />
<RecentActivityWidget />
</div>
<ProductOverviewWidget />
<ProductOverviewWidget /> -->
</div>
<AppFooter />
</div>

View File

@ -1,9 +1,14 @@
<script setup>
import { ref, onMounted } from 'vue'
import { ref, watch, onMounted } from 'vue'
import MQTTService from '../../services/mqtt.js'
const props = defineProps({
deviceId: String
})
const nodes = ref([])
const filters = ref({})
const filterMode = ref({ label: 'Lenient', value: 'lenient' });
const mqtt = new MQTTService()
@ -13,26 +18,30 @@ device -> property tree
*/
const devices = {}
/*
Convert nested object -> PrimeVue TreeTable format
*/
function buildNodes() {
nodes.value = Object.entries(devices).map(([deviceId, tree]) => ({
key: deviceId,
data: { name: deviceId },
children: buildTree(tree, deviceId)
}))
}
// /*
// Convert nested object -> PrimeVue TreeTable format
// */
// function buildNodes() {
// nodes.value = Object.entries(devices).map(([deviceId, tree]) => ({
// key: deviceId,
// data: { name: deviceId },
// children: buildTree(tree, deviceId)
// }))
// }
function buildTree(obj, path) {
let propertyTree = {}
// function buildTree(obj, path) {
function buildNodes(obj, path='') {
return Object.entries(obj).map(([key, val]) => {
const fullKey = `${path}/${key}`
// const fullKey = `${path}/${key}`
const fullKey = path ? `${path}/${key}` : key
if (val && typeof val === 'object' && !('value' in val)) {
return {
key: fullKey,
data: { name: key },
children: buildTree(val, fullKey)
children: buildNodes(val, fullKey)
}
}
@ -49,13 +58,11 @@ function buildTree(obj, path) {
/*
Insert MQTT property into nested tree
*/
function insertProperty(deviceId, propertyPath, value) {
if (!devices[deviceId]) devices[deviceId] = {}
function insertProperty(pathParts, value) {
let node = propertyTree
let node = devices[deviceId]
propertyPath.forEach((part, i) => {
if (i === propertyPath.length - 1) {
pathParts.forEach((part, i) => {
if (i === pathParts.length - 1) {
node[part] = { value }
} else {
if (!node[part]) node[part] = {}
@ -63,19 +70,25 @@ function insertProperty(deviceId, propertyPath, value) {
}
})
buildNodes()
nodes.value = buildNodes(propertyTree)
}
watch(() => props.deviceId, () => {
propertyTree = {}
nodes.value = []
})
onMounted(() => {
mqtt.subscribe('device/+/property/#', (payload, topic) => {
const parts = topic.split('/')
const deviceId = parts[1]
const device = parts[1]
const propertyPath = parts.slice(3)
insertProperty(deviceId, propertyPath, payload)
if (device !== props.deviceId) return
insertProperty(propertyPath, payload)
})
})
@ -84,7 +97,16 @@ onMounted(() => {
<template>
<div class="card">
<TreeTable :value="nodes" :filters="filters" filterMode="lenient">
<TreeTable :value="nodes" :filters="filters" :filterMode="filterMode.value">
<template #header>
<div class="flex products-header">
<span class="products-title">Properties</span>
<IconField class="search-field">
<InputIcon class="pi pi-search" />
<InputText v-model="filters['global']" placeholder="Filter by..." />
</IconField>
</div>
</template>
<template #empty> No properties available.</template>
<Column field="name" header="Name" expander style="min-width: 12rem">
<template #filter>