good enough

This commit is contained in:
Jono Targett 2026-03-17 15:00:32 +10:30
parent d8cdbcd0cc
commit 7ced5a1662
2 changed files with 78 additions and 29 deletions

View File

@ -1,7 +1,13 @@
<script setup>
import { useLayout } from "../composables/useLayout";
import { onMounted } from 'vue'
const { primaryColors, surfaces, primary, surface, isDarkMode, updateColors, toggleDarkMode } = useLayout();
onMounted(() => {
toggleDarkMode()
})
const { primaryColors, surfaces, primary, surface, isDarkMode, updateColors } = useLayout();
</script>
<template>

View File

@ -13,6 +13,10 @@ import {basicSetup} from "codemirror"
import { oneDark } from "@codemirror/theme-one-dark"
import { EditorView } from "@codemirror/view"
import { EditorState, StateEffect } from "@codemirror/state"
import { useLayout } from "../../composables/useLayout";
const { isDarkMode } = useLayout();
const lightTheme = EditorView.theme({}, { dark: false })
const darkTheme = oneDark //EditorView.theme({}, { dark: true })
@ -92,12 +96,11 @@ function createEditor(cmd, el) {
const initialDoc =
cmd.input ||
cmd.schema ||
''
const state = EditorState.create({
doc: initialDoc,
extensions: baseExtensions(currentThemeExtension)
extensions: baseExtensions(cmd, isDarkMode.value ? darkTheme : lightTheme)
})
const view = new EditorView({
@ -109,48 +112,57 @@ function createEditor(cmd, el) {
}
function baseExtensions(theme) {
function baseExtensions(cmd, theme) {
return [
basicSetup,
json(),
theme,
EditorView.updateListener.of(update => {
if (update.docChanged) {
const name = update.view.dom.dataset.command
if (name && commandMap[name]) {
commandMap[name].input = update.state.doc.toString()
}
cmd.input = update.state.doc.toString()
}
})
]
}
function updateEditorTheme() {
const dark = isDarkMode()
currentThemeExtension = dark ? darkTheme : lightTheme
Object.values(editors).forEach(view => {
Object.entries(editors).forEach(([cmd, view]) => {
console.log("changing theme of ", view)
view.dispatch({
effects: StateEffect.reconfigure.of(baseExtensions(currentThemeExtension))
effects: StateEffect.reconfigure.of(baseExtensions(cmd, isDarkMode.value ? darkTheme : lightTheme))
})
})
}
function isDarkMode() {
return document.documentElement.classList.contains('p-dark')
import Dialog from 'primevue/dialog'
const schemaDialog = reactive({
visible: false,
content: ''
})
function showSchema(cmd) {
try {
schemaDialog.content = JSON.stringify(JSON.parse(cmd.schema), null, 2)
} catch {
schemaDialog.content = cmd.schema || 'No schema available'
}
schemaDialog.visible = true
}
let currentThemeExtension = isDarkMode() ? darkTheme : lightTheme
watch(() => props.deviceId, () => {
Object.keys(commandMap).forEach(k => delete commandMap[k])
commands.value = []
})
watch(isDarkMode, () => {
console.log("Editor mode changed")
updateEditorTheme()
})
onMounted(() => {
mqtt2.subscribe('device/+/command/#', (payload, topic) => {
@ -186,6 +198,15 @@ onMounted(() => {
</script>
<template>
<Dialog
v-model:visible="schemaDialog.visible"
header="Command Schema"
:modal="true"
:closable="true"
:style="{width: '400px'}"
>
<pre>{{ schemaDialog.content }}</pre>
</Dialog>
<div class="layout-card">
<DataView :value="commands">
<template #header>
@ -214,20 +235,26 @@ onMounted(() => {
</div>
</AccordionHeader>
<AccordionContent>
<div class="command-body">
<div class="command-content">
<!-- Left: Code editor -->
<div class="editor-container" :ref="el => setEditorRef(cmd.name, el)"></div>
<div
class="json-editor"
:ref="el => setEditorRef(cmd.name, el)"
/>
<Button
label="Send Command"
<!-- Right: Buttons -->
<div class="button-container">
<Button
icon="pi pi-question-circle"
class="p-mb-2"
@click="showSchema(cmd)"
tooltip="Show schema"
tooltipOptions="{position:'top'}"
/>
<Button
icon="pi pi-send"
class="p-mt-2"
@click="sendCommand(cmd)"
/>
tooltip="Show schema"
tooltipOptions="{position:'top'}"
/>
</div>
</div>
</AccordionContent>
@ -309,4 +336,20 @@ onMounted(() => {
outline-offset: 0;
}
.command-content {
display: flex;
gap: 1rem;
}
.editor-container {
flex: 1;
}
.button-container {
display: flex;
flex-direction: column;
gap: 0.5rem;
justify-content: flex-start; /* aligns buttons to the top */
}
</style>