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 @@ Metadata - - {{ toJSON .Channel.Metadata }} + +
+

+                          
- @@ -144,6 +140,21 @@ + diff --git a/ui/web/template/channels.html b/ui/web/template/channels.html index fe79ca68..25a10c43 100644 --- a/ui/web/template/channels.html +++ b/ui/web/template/channels.html @@ -80,13 +80,9 @@
- +
+ +
Enter channel metadata in JSON format.
@@ -176,15 +172,18 @@ {{ $c.Name }} {{ $c.Description }} - {{ range $k, $v := $c.Metadata }} - - {{ $k }}: - {{ $v }} - - {{ end }} +
+

+                              
{{ $c.CreatedAt }} + {{ end }} @@ -207,6 +206,12 @@ channelsModal.show(); } } + + codeMirrorEditor({ + textArea: "metadata", + button: "create-channel-button", + value: {}, + }); diff --git a/ui/web/template/group.html b/ui/web/template/group.html index 4620f105..e3f80435 100644 --- a/ui/web/template/group.html +++ b/ui/web/template/group.html @@ -86,25 +86,21 @@ Metadata - - {{ toJSON .Group.Metadata }} + +
+

+                          
- @@ -128,7 +124,22 @@
- + diff --git a/ui/web/template/groups.html b/ui/web/template/groups.html index ed4d4f14..b55d894c 100644 --- a/ui/web/template/groups.html +++ b/ui/web/template/groups.html @@ -80,15 +80,11 @@
- +
+ +
- Enter groups metadata in JSON format. + Enter group metadata in JSON format.
@@ -167,15 +163,18 @@ {{ $g.Description }} - {{ range $k, $v := $g.Metadata }} - - {{ $k }}: - {{ $v }} - - {{ end }} +
+

+                              
{{ $g.CreatedAt }} + {{ end }} @@ -198,6 +197,12 @@ groupsModal.show(); } } + + codeMirrorEditor({ + textArea: "metadata", + button: "create-group-button", + value: {}, + }); + + + - - {{ end }} diff --git a/ui/web/template/metadatamodal.html b/ui/web/template/metadatamodal.html new file mode 100644 index 00000000..1db3ba8c --- /dev/null +++ b/ui/web/template/metadatamodal.html @@ -0,0 +1,102 @@ + + +{{ define "metadatamodal" }} + + + + + + + + + + + + + +{{ end }} diff --git a/ui/web/template/navbar.html b/ui/web/template/navbar.html index 18dcbc36..0014d0b9 100644 --- a/ui/web/template/navbar.html +++ b/ui/web/template/navbar.html @@ -331,6 +331,8 @@

Magistrala

+ {{ template "metadatamodal" }} +
- +
Enter Domain metadata in JSON format.
-
+
@@ -466,5 +464,11 @@

{{ end }} diff --git a/ui/web/template/thing.html b/ui/web/template/thing.html index a1e4f47b..4db67268 100644 --- a/ui/web/template/thing.html +++ b/ui/web/template/thing.html @@ -111,25 +111,21 @@ Metadata - - {{ toJSON .Thing.Metadata }} + +
+

+                          
- @@ -153,7 +149,22 @@ - + diff --git a/ui/web/template/things.html b/ui/web/template/things.html index 195b1cdc..0a8c6820 100644 --- a/ui/web/template/things.html +++ b/ui/web/template/things.html @@ -98,15 +98,11 @@

- +
+ +
- Enter device metadata in JSON format. + Enter thing metadata in JSON format.
@@ -191,15 +187,18 @@ {{ end }} - {{ range $k, $v := $t.Metadata }} - - {{ $k }}: - {{ $v }} - - {{ end }} +
+

+                              
{{ $t.CreatedAt }} + {{ end }} @@ -222,6 +221,12 @@ thingsModal.show(); } } + + codeMirrorEditor({ + textArea: "metadata", + button: "create-thing-button", + value: {}, + }); diff --git a/ui/web/template/users.html b/ui/web/template/users.html index cdf0f18f..ee669934 100644 --- a/ui/web/template/users.html +++ b/ui/web/template/users.html @@ -91,13 +91,10 @@
- +
+ +
+
Enter user metadata in JSON format.
@@ -183,15 +180,18 @@ {{ end }} - {{ range $k, $v := $u.Metadata }} - - {{ $k }}: - {{ $v }} - - {{ end }} +
+

+                              
{{ $u.CreatedAt }} + {{ end }} @@ -228,6 +228,12 @@ usersModal.show(); } } + + codeMirrorEditor({ + textArea: "metadata", + button: "create-user-button", + value: {}, + });