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> <script setup>
import { useLayout } from "../composables/useLayout"; 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> </script>
<template> <template>

View File

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