Files
Vulture/VApp/src/components/MQTTDebugConsole.vue

137 lines
3.3 KiB
Vue

<template>
<v-container class="v-container-style-console">
<v-card tile outlined width="900">
<v-card-title class="card__title primary centered-title">
<v-icon left class="pr-5 pl-2" size="40">mdi-console-line</v-icon>
Console MQTT
</v-card-title>
<div class="div_topic">
<v-select
density="compact"
label="Topic"
v-model="selectedTopic"
:items="topics"
prepend-icon="mdi-target"
></v-select>
<div class="button_div_style">
<v-btn rounded @click="resetTopicFilter" color="primary">Unfilter</v-btn>
<v-btn
rounded
:class="{ 'scrolling-paused': scrollingState, 'scrolling-active': !scrollingState }"
@click="toggleScrollingState"
>
<v-icon>{{ scrollingState ? 'mdi-pause' : 'mdi-play' }}</v-icon>
</v-btn>
</div>
</div>
<v-container>
<div v-for="(log, index) in filteredLogs" :key="index">
<v-label class="v-label-timestamp">{{ log.timestamp }} -&nbsp;</v-label>
<v-label class="v-label-topic-message-title">Topic :&nbsp;</v-label>
<v-label class="v-label-topic-message">{{ log.topic }}&nbsp;</v-label>
<v-label class="v-label-topic-message-title">Msg :&nbsp;</v-label>
<v-label class="v-label-topic-message">{{ log.message }}</v-label>
</div>
</v-container>
</v-card>
</v-container>
</template>
<script setup>
import { ref, computed } from 'vue';
import { subscribeToTopic } from '@/services/mqttService';
// Data
const messageLogs = ref([]);
const selectedTopic = ref('');
const topics = ref([]);
const scrollingState = ref(true);
// Methods
const handleMessage = (topic, message) => {
const timestamp = new Date().toLocaleString('fr-FR', {
hour12: false,
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
if (scrollingState.value) {
if (!topics.value.includes(topic)) {
topics.value.push(topic);
}
messageLogs.value.unshift({ timestamp, topic, message });
if (messageLogs.value.length > 20) {
messageLogs.value.pop();
}
}
};
const resetTopicFilter = () => {
selectedTopic.value = '';
};
const toggleScrollingState = () => {
scrollingState.value = !scrollingState.value;
};
// Computed
const filteredLogs = computed(() => {
if (!selectedTopic.value) {
return messageLogs.value;
}
return messageLogs.value.filter((log) => log.topic === selectedTopic.value);
});
// Lifecycle
subscribeToTopic('#', (topic, message) => {
handleMessage(topic, message);
});
</script>
<style scoped>
.scrolling-paused {
background-color: rgba(var(--v-theme-primary)) !important;
}
.scrolling-active {
background-color: rgba(var(--v-theme-success)) !important;
}
.button_div_style {
justify-content: space-evenly;
display: flex;
}
.div_topic {
text-align: center !important;
padding: 5% 4% 1% 4%;
}
.v-container-style-console {
display: flex;
justify-content: center;
position: sticky;
top: 50px;
}
.centered-title {
text-align: center;
}
.v-label-timestamp {
opacity: 100%;
font-style: oblique;
font-weight: 400;
color: #838383;
}
.v-label-topic-message-title {
opacity: 100%;
font-weight: 700;
color: rgba(var(--v-theme-primary));
}
.v-label-topic-message {
font-weight: 300;
}
</style>