diff --git a/web/index.html b/web/index.html index d563d9d..9054bd8 100644 --- a/web/index.html +++ b/web/index.html @@ -85,7 +85,19 @@ border: 1px solid var(--ctp-mocha-surface1); border-radius: 0.25em; padding: 0.5em; - user-select: none; + max-width: min(900px, calc(100% - 10em)); + max-height: 500px; + + & > div { + margin-bottom: 0.5em; + + & > p { + margin-inline: 0.5em; + } + & > code { + margin: 0.5em; + } + } &:focus-within, &:focus-visible { @@ -151,6 +163,28 @@ } } + code { + display: block; + background-color: var(--ctp-mocha-surface1); + border-radius: 0.5em; + padding: 1em; + font-family: 'Courier New', Courier, monospace; + + & pre { + margin: 0; + padding: 0; + font-size: 1.2em; + } + } + + kbd { + background-color: var(--ctp-mocha-surface1); + border-radius: 0.25em; + padding: 0.25em; + font-family: 'Courier New', Courier, monospace; + font-size: 0.8em; + } + button { background-color: var(--ctp-mocha-surface1); color: var(--ctp-mocha-text); @@ -220,8 +254,27 @@ &[icon='copy']::before { background-image: url(https://fonts.gstatic.com/s/i/short-term/release/materialsymbolsoutlined/content_copy/default/48px.svg); } + &[icon='info']::before { + background-image: url(https://fonts.gstatic.com/s/i/short-term/release/materialsymbolsoutlined/info/default/48px.svg); + } } } + + ::-webkit-scrollbar { + width: 0.6em; + } + + ::-webkit-scrollbar-track-piece { + background-color: var(--ctp-mocha-mantle); + } + + ::-webkit-scrollbar-thumb { + background-color: var(--ctp-mocha-surface1); + } + + ::-webkit-scrollbar-thumb:hover { + background-color: var(--ctp-mocha-overlay1); + } @@ -262,6 +315,12 @@ name="api_token" id="api_token" /> +
@@ -304,6 +363,66 @@ + +
+
+

GarminHomeAssistant Web Editor

+ +
+ +

+ This is the web editor for the GarminHomeAssistant watch app, it + offers enhanced schema checking and validation over the original JSON + schema by using the HomeAssistant API to create a schema based on your + HomeAssistant configuration. +

+ +

+ This editor makes use of the same credentials as the watch app (these + can be pasted in the top bar of this page). However in order for this + editor to work, you will need to amend the CORS settings of your + HomeAssistant instance. Add this to your configuration.yaml file: +

+ + +
+http:
+  cors_allowed_origins:
+    - https://house-of-abbey.github.io
+
+ +

+ Once you have added this to your configuration.yaml file, you will + need to restart HomeAssistant. After HomeAssistant is restarted, + reload this page. +

+ +

+ Now you should have validation and autocompletion, anywhere in the + editor, press Ctrl + Space to see the available + options. You will also see red lines under syntax errors and yellow + lines under validation errors. Hover over these lines to see the + message. You can also click on the `Run Action` and `Toggle` buttons + to test your actions. +

+ +

+ In the top bar there are 4 buttons, the first button will download the + online version of your menu.json file and put it in the editor. The + second button will copy the content of the editor to the clipboard. + The third button will open the troubleshooting dialog, this will allow + you to test your HomeAssistant API connection. The fourth button will + open this dialog. +

+
+
+ diff --git a/web/main.js b/web/main.js index 1860ec1..0b747b0 100644 --- a/web/main.js +++ b/web/main.js @@ -1,3 +1,10 @@ +import { configureMonacoYaml } from 'https://cdn.jsdelivr.net/npm/monaco-yaml@5.1.1/+esm'; + +if (!localStorage.getItem('info_shown')) { + document.querySelector('#info-dialog').showModal(); + localStorage.setItem('info_shown', 'true'); +} + let api_url = localStorage.getItem('api_url') ?? ''; let menu_url = localStorage.getItem('menu_url') ?? ''; let api_token = localStorage.getItem('api_token') ?? ''; @@ -466,6 +473,8 @@ require(['vs/editor/editor.main'], async () => { }); } + configureMonacoYaml(monaco); + document.querySelector('#api_url').value = api_url; document.querySelector('#menu_url').value = menu_url; document.querySelector('#api_token').value = api_token; @@ -473,6 +482,9 @@ require(['vs/editor/editor.main'], async () => { document.querySelector('#troubleshooting').addEventListener('click', (e) => { document.querySelector('#troubleshooting-dialog').showModal(); }); + document.querySelector('#info').addEventListener('click', (e) => { + document.querySelector('#info-dialog').showModal(); + }); document.querySelector('#test-api').addEventListener('click', async (e) => { try { @@ -643,6 +655,10 @@ require(['vs/editor/editor.main'], async () => { ).then((r) => r.json()) ); + monaco.editor.colorizeElement(document.querySelector('#cors-settings'), { + theme: 'mocha', + }); + monaco.languages.registerCompletionItemProvider('json', { triggerCharacters: ['.'], provideCompletionItems: function (model, position) { diff --git a/web/types.d.ts b/web/types.d.ts index a5d4f97..3655195 100644 --- a/web/types.d.ts +++ b/web/types.d.ts @@ -1,3 +1,7 @@ declare namespace json { export function parse(text: string): import('json-ast-comments').JsonDocument; } + +declare module 'https://cdn.jsdelivr.net/npm/monaco-yaml@5.1.1/+esm' { + export * from 'monaco-yaml'; +}