Skip to content

Commit

Permalink
display attributes in UI in an aceEditor instead of a simple inputfield
Browse files Browse the repository at this point in the history
* for attributes which were JsonObjects or JsonArrays, displaying them in a single "input" field was very umcomfortable
  • Loading branch information
thjaeckle committed Nov 22, 2023
1 parent 2d6d55b commit 7b6b432
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 25 deletions.
2 changes: 1 addition & 1 deletion ui/main.scss
Expand Up @@ -156,7 +156,7 @@ textarea {
}

h5, h6 {
margin-top: 0.25rem;
margin-top: 0.5rem;
margin-bottom: 0.25rem;
}

Expand Down
33 changes: 22 additions & 11 deletions ui/modules/things/attributes.ts
Expand Up @@ -20,11 +20,11 @@ import * as Things from './things.js';
const dom = {
tbodyAttributes: null,
crudAttribute: null,
inputAttributeValue: null,
badgeAttributeCount: null,
};

let eTag;
let attributeEditor;

/**
* Initializes components. Should be called after DOMContentLoaded event
Expand All @@ -40,19 +40,23 @@ export function ready() {
dom.crudAttribute.addEventListener('onUpdateClick', onUpdateAttributeClick);
dom.crudAttribute.addEventListener('onDeleteClick', onDeleteAttributeClick);
dom.crudAttribute.addEventListener('onEditToggle', onEditToggle);

attributeEditor = Utils.createAceEditor('attributeEditor', 'ace/mode/json', true);

document.querySelector('a[data-bs-target="#tabCrudAttribute"]').addEventListener('shown.bs.tab', (event) => {
attributeEditor.renderer.updateFull();
});
}

function onCreateAttributeClick() {
Utils.assert(dom.crudAttribute.idValue, 'Attribute path must not be empty', dom.crudAttribute.validationElement);
Utils.assert(!Things.theThing['attributes'] || !Object.keys(Things.theThing.attributes).includes(dom.crudAttribute.idValue),
`Attribute path ${dom.crudAttribute.idValue} already exists in Thing`,
dom.crudAttribute.validationElement);
Utils.assert(dom.inputAttributeValue.value, 'Attribute value must not be empty', dom.inputAttributeValue);

updateAttribute('PUT', true);
}
function onUpdateAttributeClick() {
Utils.assert(dom.inputAttributeValue.value, 'Attribute value must not be empty');
updateAttribute('PUT');
}

Expand All @@ -79,10 +83,11 @@ function onAttributeTableClick(event) {
* @param {boolean} isNewAttribute if a new attribute is created. default = false
*/
function updateAttribute(method, isNewAttribute = false) {
const attributeValue = JSON.parse(attributeEditor.getValue());
API.callDittoREST(
method,
`/things/${Things.theThing.thingId}/attributes/${dom.crudAttribute.idValue}`,
method === 'PUT' ? attributeFromString(dom.inputAttributeValue.value) : null,
method === 'PUT' ? attributeValue : null,
isNewAttribute ?
{
'If-None-Match': '*'
Expand All @@ -105,10 +110,10 @@ function refreshAttribute(thing, attributePath = null) {

if (thing) {
dom.crudAttribute.idValue = attributePath;
dom.inputAttributeValue.value = attributeToString(thing.attributes[attributePath]);
attributeEditor.setValue(Utils.stringifyPretty(thing.attributes[attributePath]), -1);
} else {
dom.crudAttribute.idValue = null;
dom.inputAttributeValue.value = null;
attributeEditor.setValue('');
}
}

Expand Down Expand Up @@ -161,7 +166,6 @@ function attributeFromString(attribute) {

function onEditToggle(event) {
const isEditing = event.detail.isEditing;
dom.inputAttributeValue.disabled = !isEditing;
if (isEditing && dom.crudAttribute.idValue && dom.crudAttribute.idValue !== '') {
API.callDittoREST('GET', `/things/${Things.theThing.thingId}/attributes/${dom.crudAttribute.idValue}`,
null, null, true)
Expand All @@ -170,11 +174,18 @@ function onEditToggle(event) {
return response.json();
})
.then((attributeValue) => {
dom.inputAttributeValue.value = attributeToString(attributeValue);
enableDisableEditor();
attributeEditor.setValue(Utils.stringifyPretty(attributeValue), -1);
});
} else {
dom.inputAttributeValue.value = dom.crudAttribute.idValue ?
attributeToString(Things.theThing.attributes[dom.crudAttribute.idValue]) :
null;
enableDisableEditor();
refreshAttribute(Things.theThing, dom.crudAttribute.idValue)
attributeEditor.setValue(
Utils.stringifyPretty(Things.theThing.attributes[dom.crudAttribute.idValue]), -1);
}

function enableDisableEditor() {
attributeEditor.setReadOnly(!isEditing);
attributeEditor.renderer.setShowGutter(isEditing);
}
}
28 changes: 15 additions & 13 deletions ui/modules/things/things.html
Expand Up @@ -48,7 +48,7 @@
</table>
</div>
</div>
<div class="col-md-5 resizable_flex_column" id="details">
<div class="col-md-5 resizable_flex_column" style="height: auto" id="details">
<ul id="tabItemsThing" class="nav nav-tabs nav-fill">
<li class="nav-item">
<a class="nav-link active" data-bs-toggle="tab" data-bs-target="#tabThingDetails">Details</a>
Expand All @@ -66,7 +66,7 @@
</table>
</div>
</div>
<div class="tab-pane fade container no-margin" style="height:100%;" id="tabModifyThing">
<div class="tab-pane fade container no-margin" id="tabModifyThing">
<crud-toolbar id="crudThings" label="Thing ID">
<div class="input-group input-group-sm mb-1">
<label class="input-group-text" id="labelX">Definition</label>
Expand All @@ -92,24 +92,26 @@ <h5 data-bs-toggle="collapse" data-bs-target="#collapseAttributes">Attributes <s
<hr />
<div class="collapse" id="collapseAttributes">
<div class="row">
<div class="col-md-4" style="overflow-y:scroll;">
<div class="col-md-7 resizable_flex_column" style="overflow-y:scroll;">
<table class="table table-striped table-hover table-sm">
<thead>
<th class="col-3" style="visibility: hidden"></th>
<th class="col-7" style="visibility: hidden"></th>
</thead>
<tbody id="tbodyAttributes"></tbody>
</table>
</div>
<div class="col-md-8">
<ul class="nav nav-tabs nav-fill">
<div class="col-md-5 resizable_flex_column" style="height: auto">
<ul class="nav nav-tabs nav-fill" id="tabItemsAttribute">
<li class="nav-item">
<a class="nav-link active">Manage</a>
<a class="nav-link active" data-bs-toggle="tab" data-bs-target="#tabCrudAttribute">Manage</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane container active no-margin">
<crud-toolbar id="crudAttribute" label="Path">
<div class="input-group input-group-sm has-validation mb-1">
<label class="input-group-text">Value</label>
<input type="text" class="form-control form-control-sm" id="inputAttributeValue" disabled></input>
<div class="invalid-feedback"></div>
<div class="tab-content" style="flex-grow: 1;" id="tabContentAttribute">
<div class="tab-pane container active no-margin" id="tabCrudAttribute">
<crud-toolbar id="crudAttribute" label="Attribute key">
<div class="ace_container mb-1" style="flex-grow: 1;">
<div class="script_editor" id="attributeEditor"></div>
</div>
</crud-toolbar>
</div>
Expand Down

0 comments on commit 7b6b432

Please sign in to comment.