Readded the flash effect on property change
This commit is contained in:
parent
6f075fd49a
commit
a3c9d053aa
3
console/.gitignore
vendored
3
console/.gitignore
vendored
@ -32,3 +32,6 @@ dist-ssr
|
|||||||
.env
|
.env
|
||||||
.env.local
|
.env.local
|
||||||
.env.*.local
|
.env.*.local
|
||||||
|
|
||||||
|
|
||||||
|
.vite
|
||||||
@ -18,7 +18,7 @@ import CommandsWidget from "./components/dashboard/CommandsWidget.vue";
|
|||||||
<PropertiesWidget device-id="example-gps-fedora" />
|
<PropertiesWidget device-id="example-gps-fedora" />
|
||||||
<CommandsWidget device-id="example-gps-fedora" />
|
<CommandsWidget device-id="example-gps-fedora" />
|
||||||
</div>
|
</div>
|
||||||
<StatsWidget />
|
<!-- <StatsWidget /> -->
|
||||||
<!-- <div class="layout-grid-row">
|
<!-- <div class="layout-grid-row">
|
||||||
<SalesTrendWidget />
|
<SalesTrendWidget />
|
||||||
<RecentActivityWidget />
|
<RecentActivityWidget />
|
||||||
|
|||||||
@ -102,7 +102,7 @@ const jsonFormsConfig = {
|
|||||||
header="Command Schema"
|
header="Command Schema"
|
||||||
:modal="true"
|
:modal="true"
|
||||||
:closable="true"
|
:closable="true"
|
||||||
:style="{width: '400px'}"
|
:style="{width: '700px'}"
|
||||||
>
|
>
|
||||||
<pre>{{ schemaDialog.content }}</pre>
|
<pre>{{ schemaDialog.content }}</pre>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
@ -185,8 +185,7 @@ const jsonFormsConfig = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.command-desc {
|
.command-desc {
|
||||||
color: #666;
|
font-size: 0.8rem;
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -12,29 +12,12 @@ const filterMode = ref({ label: 'Lenient', value: 'lenient' });
|
|||||||
|
|
||||||
const mqtt = new MQTTService()
|
const mqtt = new MQTTService()
|
||||||
|
|
||||||
/*
|
const changedKeys = ref({})
|
||||||
Internal storage
|
|
||||||
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)
|
|
||||||
// }))
|
|
||||||
// }
|
|
||||||
|
|
||||||
let propertyTree = {}
|
let propertyTree = {}
|
||||||
|
|
||||||
// function buildTree(obj, path) {
|
|
||||||
function buildNodes(obj, path='') {
|
function buildNodes(obj, path='') {
|
||||||
return Object.entries(obj).map(([key, val]) => {
|
return Object.entries(obj).map(([key, val]) => {
|
||||||
// const fullKey = `${path}/${key}`
|
|
||||||
const fullKey = path ? `${path}/${key}` : key
|
const fullKey = path ? `${path}/${key}` : key
|
||||||
|
|
||||||
if (val && typeof val === 'object' && !('value' in val)) {
|
if (val && typeof val === 'object' && !('value' in val)) {
|
||||||
@ -55,12 +38,11 @@ function buildNodes(obj, path='') {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Insert MQTT property into nested tree
|
|
||||||
*/
|
|
||||||
function insertProperty(pathParts, value) {
|
function insertProperty(pathParts, value) {
|
||||||
let node = propertyTree
|
let node = propertyTree
|
||||||
|
|
||||||
|
const fullKey = pathParts.join('/')
|
||||||
|
|
||||||
pathParts.forEach((part, i) => {
|
pathParts.forEach((part, i) => {
|
||||||
if (i === pathParts.length - 1) {
|
if (i === pathParts.length - 1) {
|
||||||
node[part] = { value }
|
node[part] = { value }
|
||||||
@ -70,16 +52,26 @@ function insertProperty(pathParts, value) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 🔥 always flash on update
|
||||||
|
changedKeys.value[fullKey] = true
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
delete changedKeys.value[fullKey]
|
||||||
|
}, 600)
|
||||||
|
|
||||||
nodes.value = buildNodes(propertyTree)
|
nodes.value = buildNodes(propertyTree)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function rowClass(node) {
|
||||||
|
return changedKeys.value.has(node.key) ? 'flash-row' : ''
|
||||||
|
}
|
||||||
|
|
||||||
watch(() => props.deviceId, () => {
|
watch(() => props.deviceId, () => {
|
||||||
propertyTree = {}
|
propertyTree = {}
|
||||||
nodes.value = []
|
nodes.value = []
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
||||||
mqtt.subscribe('device/+/property/#', (payload, topic) => {
|
mqtt.subscribe('device/+/property/#', (payload, topic) => {
|
||||||
const parts = topic.split('/')
|
const parts = topic.split('/')
|
||||||
|
|
||||||
@ -117,7 +109,30 @@ onMounted(() => {
|
|||||||
<template #filter>
|
<template #filter>
|
||||||
<InputText v-model="filters['value']" type="text" placeholder="Filter by value" />
|
<InputText v-model="filters['value']" type="text" placeholder="Filter by value" />
|
||||||
</template>
|
</template>
|
||||||
|
<template #body="{ node }">
|
||||||
|
<span :class="{ 'flash-cell': changedKeys[node.key] }">
|
||||||
|
{{ node.data.value }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
</TreeTable>
|
</TreeTable>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.flash-cell {
|
||||||
|
animation: flash-bg 0.6s ease;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes flash-bg {
|
||||||
|
0% {
|
||||||
|
background-color: var(--p-primary-color);
|
||||||
|
color: var(--p-primary-color-text);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-color: transparent;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue
Block a user