Skip to content

Commit

Permalink
UI - New Operations tab (eclipse-ditto#1600)
Browse files Browse the repository at this point in the history
* UI - New Operations tab
* added new tab
* changed way to control right auth user
* extended api to allow devops path
* utils to add table row now returns row
* crud editor returns explicit cancel action
* crud editor now with option without delete or create

Signed-off-by: thfries <thomas.fries0@gmail.com>

* UI - Operations Tab: new logger view

Signed-off-by: thfries <thomas.fries0@gmail.com>

* UI - operations tab - refresh not scrolling

* UI - change header info on new files

Signed-off-by: thfries <thomas.fries0@gmail.com>

* UI - Operations tab - make tabs optional
- fixed auth header mixing from wrong environment
- operations tab not getting right auth header

Signed-off-by: thfries <thomas.fries0@gmail.com>

* UI - added option to define new logger for each service in Operations / Logging functionality

Signed-off-by: Thomas Jäckle <thomas.jaeckle@beyonnex.io>

* UI - operations tab
- remove spellcheck from input
- split loggerView into smaller functions

Signed-off-by: thfries <thomas.fries0@gmail.com>

---------

Signed-off-by: thfries <thomas.fries0@gmail.com>
Signed-off-by: Thomas Jäckle <thomas.jaeckle@beyonnex.io>
Co-authored-by: Thomas Jäckle <thomas.jaeckle@beyonnex.io>
  • Loading branch information
thfries and thjaeckle committed Mar 31, 2023
1 parent 8bca636 commit 89c646d
Show file tree
Hide file tree
Showing 19 changed files with 334 additions and 105 deletions.
12 changes: 10 additions & 2 deletions ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,16 @@
Policies
</a>
</li>
<li class="nav-item" id="tabConnections">
<li class="nav-item" id="tabConnections" data-auth="devOps">
<a class="nav-link" data-bs-target="#collapseConnections:not(.show)" data-bs-toggle="collapse">
Connections
</a>
</li>
<li class="nav-item" id="tabOperations" data-auth="devOps">
<a class="nav-link" data-bs-target="#collapseOperations:not(.show)" data-bs-toggle="collapse">
Operations
</a>
</li>
<li class="nav-item" id="tabEnvironments">
<a class="nav-link" data-bs-target="#collapseSettings:not(.show)" data-bs-toggle="collapse">
Environments
Expand Down Expand Up @@ -105,6 +110,9 @@
<div class="collapse" id=collapseConnections data-bs-parent="#page-content">
<div id="connectionsHTML"></div>
</div>
<div class="collapse" id=collapseOperations data-bs-parent="#page-content">
<div id="operationsHTML"></div>
</div>
<div class="collapse" id="collapseSettings" data-bs-parent="#page-content">
<div id="environmentsHTML"></div>
</div>
Expand Down Expand Up @@ -147,7 +155,7 @@
<div class="input-group input-group-sm mb-1 mt-1 has-validation">
<label class="input-group-text" id="label">Default</label>
<input type="text" class="form-control" disabled id="inputIdValue">
<button class="btn btn-outline-primary btn-sm" id="buttonCrudEdit"
<button class="btn btn-outline-primary btn-sm" id="buttonEdit"
data-bs-toggle="tooltip" title="Edit">
Edit
</button>
Expand Down
9 changes: 6 additions & 3 deletions ui/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import * as MessagesIncoming from './modules/things/messagesIncoming.js';
import * as Connections from './modules/connections/connections.js';
import * as ConnectionsCRUD from './modules/connections/connectionsCRUD.js';
import * as ConnectionsMonitor from './modules/connections/connectionsMonitor.js';
import * as Operations from './modules/operations/operations.js';
import * as Policies from './modules/policies/policies.js';
import * as API from './modules/api.js';
import * as Utils from './modules/utils.js';
import {WoTDescription} from './modules/things/wotDescription.js';

Expand All @@ -40,10 +40,13 @@ document.addEventListener('DOMContentLoaded', async function() {
document.getElementById('thingsHTML').innerHTML = await (await fetch('modules/things/things.html')).text();
document.getElementById('fieldsHTML').innerHTML = await (await fetch('modules/things/fields.html')).text();
document.getElementById('featuresHTML').innerHTML = await (await fetch('modules/things/features.html')).text();
document.getElementById('messagesIncomingHTML').innerHTML = await (await fetch('modules/things/messagesIncoming.html')).text();
document.getElementById('messagesIncomingHTML').innerHTML =
await (await fetch('modules/things/messagesIncoming.html')).text();
document.getElementById('policyHTML').innerHTML = await (await fetch('modules/policies/policies.html')).text();
document.getElementById('connectionsHTML').innerHTML =
await (await fetch('modules/connections/connections.html')).text();
document.getElementById('operationsHTML').innerHTML =
await (await fetch('modules/operations/operations.html')).text();
document.getElementById('environmentsHTML').innerHTML =
await (await fetch('modules/environments/environments.html')).text();
document.getElementById('authorizationHTML').innerHTML =
Expand All @@ -64,6 +67,7 @@ document.addEventListener('DOMContentLoaded', async function() {
Connections.ready();
ConnectionsCRUD.ready();
ConnectionsMonitor.ready();
Operations.ready();
Authorization.ready();
await Environments.ready();

Expand Down Expand Up @@ -94,7 +98,6 @@ document.addEventListener('DOMContentLoaded', async function() {
e.addEventListener('click', (event) => {
mainNavbar.querySelectorAll('.nav-link,.active').forEach((n) => n.classList.remove('active'));
event.currentTarget.classList.add('active');
API.setAuthHeader(event.currentTarget.parentNode.id === 'tabConnections');
});
});

Expand Down
11 changes: 9 additions & 2 deletions ui/modules/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,9 @@ export function setAuthHeader(forDevOps) {
} else if (Environments.current().devopsAuth === 'bearer') {
authHeaderKey = 'Authorization';
authHeaderValue ='Bearer ' + Environments.current().bearerDevOps;
} else {
authHeaderKey = 'Basic';
authHeaderValue = '';
}
} else {
if (Environments.current().mainAuth === 'basic') {
Expand All @@ -295,6 +298,9 @@ export function setAuthHeader(forDevOps) {
} else if (Environments.current().mainAuth === 'bearer') {
authHeaderKey = 'Authorization';
authHeaderValue ='Bearer ' + Environments.current().bearer;
} else {
authHeaderKey = 'Basic';
authHeaderValue = '';
}
}
}
Expand All @@ -306,12 +312,13 @@ export function setAuthHeader(forDevOps) {
* @param {Object} body payload for the api call
* @param {Object} additionalHeaders object with additional header fields
* @param {boolean} returnHeaders request full response instead of json content
* @param {boolean} devOps default: false. Set true to avoid /api/2 path
* @return {Object} result as json object
*/
export async function callDittoREST(method, path, body, additionalHeaders, returnHeaders = false) {
export async function callDittoREST(method, path, body, additionalHeaders, returnHeaders = false, devOps = false) {
let response;
try {
response = await fetch(Environments.current().api_uri + '/api/2' + path, {
response = await fetch(Environments.current().api_uri + (devOps ? '' : '/api/2') + path, {
method: method,
headers: {
'Content-Type': 'application/json',
Expand Down
23 changes: 5 additions & 18 deletions ui/modules/connections/connections.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
/* eslint-disable no-invalid-this */
/* eslint-disable require-jsdoc */
import * as API from '../api.js';
import * as Environments from '../environments/environments.js';
import * as Utils from '../utils.js';
import {TabHandler} from '../utils/tabHandler.js';

const observers = [];

Expand All @@ -39,13 +39,11 @@ let dom = {
let selectedConnectionId;

export function ready() {
Environments.addChangeListener(onEnvironmentChanged);

Utils.getAllElementsById(dom);
new TabHandler(dom.tabConnections, dom.collapseConnections, refreshTab, 'disableConnections');

Utils.addValidatorToTable(dom.tbodyConnections, dom.tableValidationConnections);

dom.tabConnections.onclick = onTabActivated;
dom.buttonLoadConnections.onclick = loadConnections;
dom.tbodyConnections.addEventListener('click', onConnectionsTableClick);
}
Expand Down Expand Up @@ -100,21 +98,10 @@ function onConnectionsTableClick(event) {
}
}

let viewDirty = false;

function onTabActivated() {
if (viewDirty) {
loadConnections();
viewDirty = false;
}
}

function onEnvironmentChanged() {
if (dom.collapseConnections.classList.contains('show')) {
function refreshTab(otherEnvironment) {
if (otherEnvironment) {
selectedConnectionId = null;
setConnection(null);
loadConnections();
} else {
viewDirty = true;
}
loadConnections();
}
2 changes: 1 addition & 1 deletion ui/modules/connections/connectionsCRUD.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ function setConnection(connection) {
}

function onEditToggle(event) {
const isEditing = event.detail;
const isEditing = event.detail.isEditing;
dom.buttonConnectionTemplates.disabled = !isEditing;
connectionEditor.setReadOnly(!isEditing);
connectionEditor.renderer.setShowGutter(isEditing);
Expand Down
14 changes: 10 additions & 4 deletions ui/modules/environments/authorization.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ let dom = {
collapseConnections: null,
};

let _forDevops = false;

export function setForDevops(forDevops) {
_forDevops = forDevops;
API.setAuthHeader(_forDevops);
}

export function ready() {
Utils.getAllElementsById(dom);

Expand All @@ -53,15 +60,14 @@ export function ready() {
}

const mainAuths = document.querySelectorAll('input[name="main-auth"]');
for(let i = 0; i < mainAuths.length; i++) {
for (let i = 0; i < mainAuths.length; i++) {
mainAuths[i].checked = mainAuths[i].value === mainAuth;
}

const devopsAuths = document.querySelectorAll('input[name="devops-auth"]');
for(let i = 0; i < devopsAuths.length; i++) {
for (let i = 0; i < devopsAuths.length; i++) {
devopsAuths[i].checked = devopsAuths[i].value === devopsAuth;
}

};

document.getElementById('authorizeSubmit').onclick = () => {
Expand Down Expand Up @@ -94,5 +100,5 @@ export function onEnvironmentChanged() {
dom.dittoPreAuthenticatedUsername.value = Environments.current().dittoPreAuthenticatedUsername ?
Environments.current().dittoPreAuthenticatedUsername :
'';
API.setAuthHeader(dom.collapseConnections.classList.contains('show'));
API.setAuthHeader(_forDevops);
}
17 changes: 15 additions & 2 deletions ui/modules/environments/environments.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,27 @@ <h5>Environments</h5>
title="A comma-separated list of namespaces (e.g. com.example.namespace). The given namespaces are used as a parameter for the Things search">Search Namespaces</label>
<input type="text" class="form-control form-control-sm" spellcheck="false" id="inputSearchNamespaces" disabled></input>
</div>
<div class="input-group input-group-sm mt-1">
<div class="input-group input-group-sm mt-1 mb-3">
<label class="input-group-text">Ditto Version</label>
<select class="form-select form-select-sm" id="selectDittoVersion" disabled>
<option selecte value="3">3</option>
<option value="2">2</option>
</select>
</div>
</crud-toolbar>
<label class="form-label">Optional Tabs</label>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="inputTabPolicies" disabled>
<label class="form-check-label" for="inputTabPolicies">Policies</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="inputTabConnections" disabled>
<label class="form-check-label" for="inputTabConnections">Connections</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="inputTabOperations" disabled>
<label class="form-check-label" for="inputTabOperations">Operations</label>
</div>
</crud-toolbar>
</div>
<div class="tab-pane container no-margin" id="tabEnvJson">
<crud-toolbar label="Name" id="crudEnvironmentJson" allowIdChange>
Expand Down
27 changes: 21 additions & 6 deletions ui/modules/environments/environments.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ let dom = {
inputApiUri: null,
inputSearchNamespaces: null,
selectDittoVersion: null,
inputTabPolicies: null,
inputTabConnections: null,
inputTabOperations: null,
};

let observers = [];
Expand Down Expand Up @@ -170,6 +173,9 @@ function onUpdateEnvironmentClick(event) {
environments[selectedEnvName].api_uri = dom.inputApiUri.value;
environments[selectedEnvName].searchNamespaces = dom.inputSearchNamespaces.value;
environments[selectedEnvName].ditto_version = dom.selectDittoVersion.value;
environments[selectedEnvName].disablePolicies = !dom.inputTabPolicies.checked;
environments[selectedEnvName].disableConnections = !dom.inputTabConnections.checked;
environments[selectedEnvName].disableOperations = !dom.inputTabOperations.checked;
} else {
environments[selectedEnvName] = JSON.parse(settingsEditor.getValue());
}
Expand Down Expand Up @@ -223,13 +229,19 @@ function updateEnvEditors() {
dom.inputApiUri.value = selectedEnvironment.api_uri;
dom.inputSearchNamespaces.value = selectedEnvironment.searchNamespaces ?? '';
dom.selectDittoVersion.value = selectedEnvironment.ditto_version ? selectedEnvironment.ditto_version : '3';
dom.inputTabPolicies.checked = !selectedEnvironment.disablePolicies;
dom.inputTabConnections.checked = !selectedEnvironment.disableConnections;
dom.inputTabOperations.checked = !selectedEnvironment.disableOperations;
} else {
dom.crudEnvironmentFields.idValue = null;
dom.crudEnvironmentJson.idValue = null;
settingsEditor.setValue('');
dom.inputApiUri.value = null;
dom.inputSearchNamespaces.value = null;
dom.selectDittoVersion.value = 3;
dom.inputTabPolicies.checked = true;
dom.inputTabConnections.checked = true;
dom.inputTabOperations.checked = true;
}
}

Expand Down Expand Up @@ -304,12 +316,15 @@ async function loadEnvironmentTemplates() {
}

function onEditToggle(event) {
dom.inputApiUri.disabled = !event.detail;
dom.inputSearchNamespaces.disabled = !event.detail;
dom.selectDittoVersion.disabled = !event.detail;
settingsEditor.setReadOnly(!event.detail);
settingsEditor.renderer.setShowGutter(event.detail);
if (!event.detail) {
dom.inputApiUri.disabled = !event.detail.isEditing;
dom.inputSearchNamespaces.disabled = !event.detail.isEditing;
dom.selectDittoVersion.disabled = !event.detail.isEditing;
dom.inputTabPolicies.disabled = !event.detail.isEditing;
dom.inputTabConnections.disabled = !event.detail.isEditing;
dom.inputTabOperations.disabled = !event.detail.isEditing;
settingsEditor.setReadOnly(!event.detail.isEditing);
settingsEditor.renderer.setShowGutter(event.detail.isEditing);
if (!event.detail.isEditing) {
updateEnvEditors();
}
}
49 changes: 49 additions & 0 deletions ui/modules/operations/operations.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!--
~ Copyright (c) 2023 Contributors to the Eclipse Foundation
~
~ See the NOTICE file(s) distributed with this work for additional
~ information regarding copyright ownership.
~
~ This program and the accompanying materials are made available under the
~ terms of the Eclipse Public License 2.0 which is available at
~ http://www.eclipse.org/legal/epl-2.0
~
~ SPDX-License-Identifier: EPL-2.0
-->
<h5>Ditto Services Logging</h5>
<hr />
<div class="input-group input-group-sm mt-1 mb-1" role="group">
<div style="flex-grow: 1;"></div>
<button class="btn btn-outline-primary btn-sm button_round_left" id="buttonLoadAllLogLevels">
<i class="bi bi-arrow-clockwise"></i>
Refresh
</button>
</div>
<div class="row resizable_pane" style="height: 80vh">
<div class="col-md-12 resizable_flex_column">
<div id="divLoggers"></div>
<template id="templateLogger">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.8.3/font/bootstrap-icons.min.css"
rel="stylesheet"
integrity="sha512-YzwGgFdO1NQw1CZkPoGyRkEnUTxPSbGWXvGiXrWk8IeSqdyci0dEDYdLLjMxq1zCoU0QBa4kHAFiRhUL3z2bow=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<link href="index.css" rel="stylesheet" />

<div class="input-group input-group-sm mb-1">
<input class="form-control" type="text" disabled id="inputLogger" spellcheck="false"></input>
<div class="btn-group" role="group">
<input type="radio" class="btn-check" id="debug" autocomplete="off">
<label class="btn btn-sm btn-outline-secondary" for="debug">DEBUG</label>
<input type="radio" class="btn-check" id="info" autocomplete="off">
<label class="btn btn-sm btn-outline-success" for="info">INFO</label>
<input type="radio" class="btn-check" id="warn" autocomplete="off">
<label class="btn btn-sm btn-outline-warning" for="warn">WARN</label>
<input type="radio" class="btn-check" id="error" autocomplete="off">
<label class="btn btn-sm btn-outline-danger" for="error">ERROR</label>
</div>
</div>
</template>
</div>
</div>
Loading

0 comments on commit 89c646d

Please sign in to comment.