diff --git a/ui/service.go b/ui/service.go index 080fb643..2380f479 100644 --- a/ui/service.go +++ b/ui/service.go @@ -74,6 +74,7 @@ var ( "tablefooter", "error", "breadcrumb", + "metadatamodal", "bootstrap", "bootstraps", diff --git a/ui/web/static/css/styles.css b/ui/web/static/css/styles.css index b7d934ae..dac758f8 100644 --- a/ui/web/static/css/styles.css +++ b/ui/web/static/css/styles.css @@ -2,6 +2,8 @@ SPDX-License-Identifier: Apache-2.0 */ @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@300&family=Roboto:wght@400&family=Montserrat:wght@700&display=swap"); +@import url('https://fonts.googleapis.com/css2?family=Inconsolata&display=swap'); + :root { --main-color: #003366; @@ -15,6 +17,8 @@ SPDX-License-Identifier: Apache-2.0 */ --pill-color-1: #1d2231; --pill-color-2: #003366; --pill-color-3: #8390a2; + + --codemirror-font: 'Inconsolata', monospace; } * { @@ -220,12 +224,11 @@ body.sidebar-toggled .main-content { margin-left: 0.25rem; } -.main-content .body-button { +body .body-button { background: var(--main-color); border-radius: var(--border-radius); color: #fff; font-size: 1rem; - padding: 0.5rem 1rem; border: 1px solid var(--main-color); margin-bottom: 0.5rem; } @@ -237,7 +240,7 @@ body.sidebar-toggled .main-content { } .main-content .sendMessage-button:hover, -.main-content .body-button:hover { +body .body-button:hover { color: #fff; background: var(--main-color); transform: scale(1.03); @@ -537,7 +540,6 @@ button.edit-btn { border-radius: var(--border-radius); color: #fff; font-size: 1rem; - padding: 0.5rem 1rem; border: 1px solid var(--main-color); } @@ -585,6 +587,44 @@ button.edit-btn { font-size: 1.25rem; } +.string, +.cm-s-default .cm-string { + color: var(--main-color); +} + +.key, +.cm-property { + color: red !important; +} + +.number, +.cm-s-default .cm-number { + color: darkorange; +} + +.boolean, +.cm-s-default .cm-atom { + color: green; +} + +.null { + color: magenta; +} + +.table-container .meta-div { + overflow: auto; + max-height: 5rem; + max-width: 100%; +} + +.table-container .meta-col { + max-width: 50%; +} + +.metadata-field span { + font-family: var(--codemirror-font) !important; +} + @media (max-width: 768px) { .sidebar { width: var(--sidebar-min); diff --git a/ui/web/static/js/formatjson.js b/ui/web/static/js/formatjson.js new file mode 100644 index 00000000..88b865c3 --- /dev/null +++ b/ui/web/static/js/formatjson.js @@ -0,0 +1,49 @@ +// Copyright (c) Abstract Machines +// SPDX-License-Identifier: Apache-2.0 + +function syntaxHighlight(json) { + json = json.replace(/&/g, "&").replace(//g, ">"); + return json.replace( + /("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, + function (match) { + var cls = "number"; + if (/^"/.test(match)) { + if (/:$/.test(match)) { + cls = "key"; + } else { + cls = "string"; + } + } else if (/true|false/.test(match)) { + cls = "boolean"; + } else if (/null/.test(match)) { + cls = "null"; + } + return '' + match + ""; + }, + ); +} + +function attachFormatJsonWithPrettifyListener(config) { + document.addEventListener("DOMContentLoaded", function () { + var meta = JSON.parse(config.metadata); + document.getElementById(config.id).innerHTML = syntaxHighlight(JSON.stringify(meta, null, 2)); + }); +} + +function codeMirrorEditor(config) { + var editor = CodeMirror.fromTextArea(document.getElementById(config.textArea), { + mode: "application/json", + matchBrackets: true, + autoCloseBrackets: true, + lineWrapping: true, + lineNumbers: true, + lint: true, + gutters: ["CodeMirror-lint-markers"], + autoRefresh: true, + }); + editor.setValue(JSON.stringify(config.value, null, 2)); + editor.setSize("100%", 200); + document.getElementById(config.button).addEventListener("click", function () { + document.getElementById(config.textArea).value = editor.getValue(); + }); +} diff --git a/ui/web/static/js/update.js b/ui/web/static/js/update.js index 93058fed..4f7d1413 100644 --- a/ui/web/static/js/update.js +++ b/ui/web/static/js/update.js @@ -50,9 +50,9 @@ function updateIdentity(config) { function updateMetadata(config) { const button = document.getElementById(config.button); - button.addEventListener("click", function (event) { - const updatedValue = config.cell.textContent.trim(); + event.preventDefault(); + const updatedValue = document.getElementById(config.textArea).value; if (validateJSON(updatedValue, config.alertDiv, config.fieldName, event)) { const url = `/${config.entity}/${config.id}`; const data = { [config.field]: JSON.parse(updatedValue) }; diff --git a/ui/web/template/channel.html b/ui/web/template/channel.html index 3a1fbb6d..d6216c92 100644 --- a/ui/web/template/channel.html +++ b/ui/web/template/channel.html @@ -97,25 +97,21 @@