Skip to content

Commit

Permalink
UI - migrate to typescript
Browse files Browse the repository at this point in the history
Signed-off-by: thfries <thomas.fries0@gmail.com>
  • Loading branch information
thfries committed Jul 11, 2023
1 parent 42ea47f commit 20c5e52
Show file tree
Hide file tree
Showing 28 changed files with 204 additions and 155 deletions.
2 changes: 1 addition & 1 deletion ui/build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as esbuild from 'esbuild';
import {sassPlugin} from 'esbuild-sass-plugin';

const config = {
entryPoints: ['main.js'],
entryPoints: ['main.ts'],
bundle: true,
outdir: 'dist',
loader: {
Expand Down
4 changes: 4 additions & 0 deletions ui/custom.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module "*.html" {
const content: string;
export default content;
}
11 changes: 6 additions & 5 deletions ui/main.js → ui/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,14 @@ document.addEventListener('DOMContentLoaded', async function() {
// make tables toggle background on selection
document.querySelectorAll('.table').forEach((e) => {
e.addEventListener('click', (event) => {
if (event.target && event.target.tagName === 'TD') {
Array.from(event.target.parentNode.parentNode.children).forEach((n) => {
if (n !== event.target.parentNode) {
const target = event.target as HTMLElement;
if (target && target.tagName === 'TD') {
Array.from(target.parentNode.parentNode.children).forEach((n) => {
if (n !== target.parentNode) {
n.classList.remove('table-active');
}
});
event.target.parentNode.classList.toggle('table-active');
target.parentElement.classList.toggle('table-active');
}
});
});
Expand All @@ -120,7 +121,7 @@ document.addEventListener('DOMContentLoaded', async function() {
const {get, set} = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value');
document.querySelectorAll('input').forEach((input) => {
input.addEventListener('change', (event) => {
event.target.classList.remove('is-invalid');
(event.target as HTMLElement).classList.remove('is-invalid');
});
Object.defineProperty(input, 'value', {
get() {
Expand Down
24 changes: 16 additions & 8 deletions ui/modules/api.js → ui/modules/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,8 @@ export function setAuthHeader(forDevOps) {
* @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, devOps = false) {
export async function callDittoREST(method, path, body = null,
additionalHeaders = null, returnHeaders = false, devOps = false) {
let response;
try {
response = await fetch(Environments.current().api_uri + (devOps ? '' : '/api/2') + path, {
Expand Down Expand Up @@ -373,10 +374,22 @@ export function getEventSource(thingIds, urlParams) {
* @param {*} command optional command
* @return {*} promise to the result
*/
export async function callConnectionsAPI(operation, successCallback, connectionId, connectionJson, command) {
export async function callConnectionsAPI(operation, successCallback, connectionId = '', connectionJson = null, command = null) {
Utils.assert((env() !== 'things' || Environments.current().solutionId), 'No solutionId configured in environment');
const params = config[env()][operation];
let response;
let body;
if (params.body) {
body = JSON.stringify(params.body)
.replace('{{connectionId}}', connectionId)
.replace('"{{connectionJson}}"', JSON.stringify(connectionJson))
.replace('{{command}}', command);
} else if (connectionJson) {
body = JSON.stringify(connectionJson);
} else {
body = command;
}

try {
response = await fetch(Environments.current().api_uri + params.path.replace('{{solutionId}}',
Environments.current().solutionId).replace('{{connectionId}}', connectionId), {
Expand All @@ -385,12 +398,7 @@ export async function callConnectionsAPI(operation, successCallback, connectionI
'Content-Type': operation === 'connectionCommand' ? 'text/plain' : 'application/json',
[authHeaderKey]: authHeaderValue,
},
body: params.body ?
JSON.stringify(params.body)
.replace('{{connectionId}}', connectionId)
.replace('"{{connectionJson}}"', JSON.stringify(connectionJson))
.replace('{{command}}', command) :
connectionJson ? JSON.stringify(connectionJson) : command,
...(body) && {body: body},
});
} catch (err) {
Utils.showError(err);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ let selectedConnectionId;

export function ready() {
Utils.getAllElementsById(dom);
new TabHandler(dom.tabConnections, dom.collapseConnections, refreshTab, 'disableConnections');
TabHandler(dom.tabConnections, dom.collapseConnections, refreshTab, 'disableConnections');

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

dom.buttonLoadConnections.onclick = loadConnections;
dom.tbodyConnections.addEventListener('click', onConnectionsTableClick);
}

export function setConnection(connection, isNewConnection) {
export function setConnection(connection, isNewConnection = false) {
selectedConnectionId = connection ? connection.id : null;
notifyAll(connection, isNewConnection);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export function ready() {

function onScriptEditorBlur(scriptEditor, fieldName) {
return () => {
if (!crudConnection.isEditing || hasErrors) {
if (!dom.crudConnection.isEditing || hasErrors) {
return;
}
const editConnection = JSON.parse(connectionEditor.getValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export function ready() {

// Status --------------
dom.buttonRetrieveConnectionStatus.onclick = retrieveConnectionStatus;
document.querySelector('a[data-bs-target="#tabConnectionStatus"]').onclick = retrieveConnectionStatus;
(document.querySelector('a[data-bs-target="#tabConnectionStatus"]') as HTMLElement).onclick = retrieveConnectionStatus;

// Logs --------------
dom.buttonEnableConnectionLogs.onclick = onEnableConnectionLogsClick;
Expand All @@ -59,7 +59,7 @@ export function ready() {

// Metrics ---------------
dom.buttonRetrieveConnectionMetrics.onclick = retrieveConnectionMetrics;
document.querySelector('a[data-bs-target="#tabConnectionMetrics"]').onclick = retrieveConnectionMetrics;
(document.querySelector('a[data-bs-target="#tabConnectionMetrics"]') as HTMLElement).onclick = retrieveConnectionMetrics;
dom.buttonResetConnectionMetrics.onclick = onResetConnectionMetricsClick;
// dom.inputConnectionLogFilter.onchange = onConnectionLogFilterChange;
}
Expand Down Expand Up @@ -179,7 +179,7 @@ const knownFields = ['category', 'type', 'level'];

function onConnectionLogFilterChange(event) {
if (event.target.value && event.target.value !== '') {
connectionLogsFilter = new JsonFilter();
connectionLogsFilter = JsonFilter();
event.target.value.split(/(\s+)/).forEach((elem) => {
const keyValue = elem.split(':');
if (keyValue.length === 2 && knownFields.includes(keyValue[0].trim())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,19 @@ export function ready() {
}
}

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

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

document.getElementById('authorizeSubmit').onclick = () => {
const mainAuthSelector = document.querySelector('input[name="main-auth"]:checked');
const mainAuthSelector = document.querySelector('input[name="main-auth"]:checked') as HTMLInputElement;
const mainAuth = mainAuthSelector ? mainAuthSelector.value : undefined;
const devopsAuthSelector = document.querySelector('input[name="devops-auth"]:checked');
const devopsAuthSelector = document.querySelector('input[name="devops-auth"]:checked') as HTMLInputElement;
const devopsAuth = devopsAuthSelector ? devopsAuthSelector.value : undefined;
Environments.current().mainAuth = mainAuth;
Environments.current().devopsAuth = devopsAuth;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
/* eslint-disable arrow-parens */
/* eslint-disable prefer-const */
/* eslint-disable require-jsdoc */
import * as Authorization from '../environments/authorization.js';
import * as Authorization from './authorization.js';
import * as Utils from '../utils.js';
import defaultTemplates from './environmentTemplates.json';
import environmentsHTML from './environments.html';
Expand Down Expand Up @@ -85,9 +85,9 @@ export function addChangeListener(observer) {
observers.push(observer);
}

function notifyAll(modifiedField) {
function notifyAll(modifiedField = null) {
// Notify Authorization first to set right auth header
Authorization.onEnvironmentChanged(modifiedField);
Authorization.onEnvironmentChanged();
// Notify others
observers.forEach(observer => observer.call(null, modifiedField));
}
Expand Down Expand Up @@ -198,7 +198,7 @@ function onUpdateEnvironmentClick(event) {
}
}

export function environmentsJsonChanged(modifiedField) {
export function environmentsJsonChanged(modifiedField = null) {
environments && localStorage.setItem(STORAGE_KEY, JSON.stringify(environments));

updateEnvSelector();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ document.getElementById('operationsHTML').innerHTML = operationsHTML;

export async function ready() {
Utils.getAllElementsById(dom);
new TabHandler(dom.tabOperations, dom.collapseOperations, loadAllLogLevels, 'disableOperations');
TabHandler(dom.tabOperations, dom.collapseOperations, loadAllLogLevels, 'disableOperations');

dom.buttonLoadAllLogLevels.onclick = loadAllLogLevels;
}
Expand All @@ -53,9 +53,14 @@ function loadAllLogLevels() {

function createLoggerView(allLogLevels) {
dom.divLoggers.innerHTML = '';

type LogLevel = {
loggerConfigs?: object[]
}

Object.keys(allLogLevels).sort().forEach((service, i) => {
addHeading(service, i);
Object.values(allLogLevels[service])[0].loggerConfigs.forEach((logConfig) => {
(Object.values(allLogLevels[service]) as LogLevel[])[0].loggerConfigs.forEach((logConfig) => {
addLoggerRowForConfig(service, logConfig);
});
addLoggerRowForNew(service);
Expand All @@ -74,12 +79,12 @@ function createLoggerView(allLogLevels) {
let row = document.createElement('div');
row.attachShadow({mode: 'open'});
row.shadowRoot.append(dom.templateLogger.content.cloneNode(true));
row.shadowRoot.getElementById('inputLogger').value = logConfig.logger;
(row.shadowRoot.getElementById('inputLogger') as HTMLInputElement).value = logConfig.logger;
row.shadowRoot.getElementById(logConfig.level).setAttribute('checked', '');
Array.from(row.shadowRoot.querySelectorAll('.btn-check')).forEach((btn) => {
btn.addEventListener('click', (event) => onUpdateLoggingClick(service, {
logger: logConfig.logger,
level: event.target.id,
level: (event.target as Element).id,
}));
});
dom.divLoggers.append(row);
Expand All @@ -89,13 +94,13 @@ function createLoggerView(allLogLevels) {
let newLoggerRow = document.createElement('div');
newLoggerRow.attachShadow({mode: 'open'});
newLoggerRow.shadowRoot.append(dom.templateLogger.content.cloneNode(true));
let inputLoggerElement = newLoggerRow.shadowRoot.getElementById('inputLogger');
let inputLoggerElement = newLoggerRow.shadowRoot.getElementById('inputLogger') as HTMLInputElement;
inputLoggerElement.disabled = false;
inputLoggerElement.placeholder = 'Add new logger name and choose log level';
Array.from(newLoggerRow.shadowRoot.querySelectorAll('.btn-check')).forEach((btn) => {
btn.addEventListener('click', (event) => onUpdateLoggingClick(service, {
logger: inputLoggerElement.value,
level: event.target.id,
level: (event.target as Element).id,
}));
});
dom.divLoggers.append(newLoggerRow);
Expand Down
26 changes: 14 additions & 12 deletions ui/modules/policies/policies.js → ui/modules/policies/policies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import * as Things from '../things/things.js';
import {TabHandler} from '../utils/tabHandler.js';
import policyTemplates from './policyTemplates.json';
import policyHTML from './policies.html';
import * as ace from 'ace-builds/src-noconflict/ace';


let thePolicy;
let selectedEntry;
Expand Down Expand Up @@ -42,14 +44,14 @@ let dom = {
tabPolicies: null,
};

let subjectEditor;
let resourceEditor;
let subjectEditor: ace.Editor;
let resourceEditor: ace.Editor;

document.getElementById('policyHTML').innerHTML = policyHTML;

export function ready() {
Utils.getAllElementsById(dom);
tabHandler = new TabHandler(dom.tabPolicies, dom.collapsePolicies, refreshAll, 'disablePolicies');
tabHandler = TabHandler(dom.tabPolicies, dom.collapsePolicies, refreshAll, 'disablePolicies');

Utils.addDropDownEntries(dom.ulResourceTemplates, Object.keys(policyTemplates.resources));

Expand All @@ -72,7 +74,7 @@ export function ready() {
selectedEntry = null;
selectedResource = null;
selectedSubject = null;
Utils.tableAdjustSelection(tbodyWhoami, () => false);
Utils.tableAdjustSelection(dom.tbodyWhoami, () => false);
setEntry(null);
} else {
selectedEntry = event.target.textContent;
Expand All @@ -98,11 +100,11 @@ export function ready() {
dom.tbodyPolicySubjects.onclick = (event) => {
if (selectedSubject === event.target.parentNode.id) {
selectedSubject = null;
Utils.tableAdjustSelection(tbodyWhoami, () => false);
Utils.tableAdjustSelection(dom.tbodyWhoami, () => false);
subjectEditor.setValue('');
} else {
selectedSubject = event.target.parentNode.id;
Utils.tableAdjustSelection(tbodyWhoami, (row) => row.id === selectedSubject);
Utils.tableAdjustSelection(dom.tbodyWhoami, (row) => row.id === selectedSubject);
subjectEditor.setValue(
JSON.stringify(thePolicy.entries[selectedEntry].subjects[selectedSubject], null, 2), -1);
}
Expand Down Expand Up @@ -185,7 +187,7 @@ export function ready() {

dom.ulResourceTemplates.addEventListener('click', (event) => {
dom.inputResourceId.value = event.target.textContent;
resourceEditor.setValue(JSON.stringify(policyTemplates.resources[dom.inputResourceId.value], 0, 2), -1);
resourceEditor.setValue(JSON.stringify(policyTemplates.resources[dom.inputResourceId.value], null, 2), -1);
});

// WhoAmI -------------
Expand All @@ -197,7 +199,7 @@ export function ready() {
Things.addChangeListener(onThingChanged);
}

function validations(entryFilled, entrySelected, subjectFilled, subjectSelected, resourceFilled, resourceSelected) {
function validations(entryFilled, entrySelected = false, subjectFilled = false, subjectSelected = false, resourceFilled = false, resourceSelected = false) {
Utils.assert(thePolicy, 'Please load a policy', dom.inputPolicyId);
if (entryFilled) {
Utils.assert(dom.inputPolicyEntry.value, 'Please enter a label for the entry', dom.inputPolicyEntry);
Expand Down Expand Up @@ -240,7 +242,7 @@ function refreshWhoAmI() {
function refreshPolicy(policyId) {
API.callDittoREST('GET', '/policies/' + policyId)
.then((policy) => setThePolicy(policy))
.catch(() => setThePolicy());
.catch(() => setThePolicy(null));
};

function setThePolicy(policy) {
Expand Down Expand Up @@ -269,7 +271,7 @@ function setThePolicy(policy) {
}
};

function setEntry(policy, entryLabel) {
function setEntry(policy, entryLabel = null) {
dom.tbodyPolicySubjects.innerHTML = '';
dom.tbodyPolicyResources.innerHTML = '';
dom.inputSubjectId.value = null;
Expand Down Expand Up @@ -299,14 +301,14 @@ function setEntry(policy, entryLabel) {
}
};

function putOrDeletePolicyEntry(entry, value) {
function putOrDeletePolicyEntry(entry, value = null) {
API.callDittoREST(value ? 'PUT' : 'DELETE',
`/policies/${thePolicy.policyId}/entries/${entry}`,
value
).then(() => refreshPolicy(thePolicy.policyId));
};

function modifyPolicyEntry(type, key, value) {
function modifyPolicyEntry(type, key, value = null) {
API.callDittoREST(value ? 'PUT' : 'DELETE',
`/policies/${thePolicy.policyId}/entries/${selectedEntry}${type}${key}`, value
).then(() => refreshPolicy(thePolicy.policyId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ function onAttributeTableClick(event) {
* @param {String} method PUT or DELETE
* @param {boolean} isNewAttribute if a new attribute is created. default = false
*/
function updateAttribute(method, isNewAttribute) {
function updateAttribute(method, isNewAttribute = false) {
API.callDittoREST(
method,
`/things/${Things.theThing.thingId}/attributes/${dom.crudAttribute.idValue}`,
Expand All @@ -98,7 +98,7 @@ function updateAttribute(method, isNewAttribute) {
});
}

function refreshAttribute(thing, attributePath) {
function refreshAttribute(thing, attributePath = null) {
if (dom.crudAttribute.isEditing) {
return;
}
Expand Down
File renamed without changes.

0 comments on commit 20c5e52

Please sign in to comment.