return section
}
-// Create div and table for template or message:
-function createForMessage(message, isMessage) {
+// Create div and table for template:
+function createForTemplate(template) {
const div = document.createElement('div')
div.setAttribute('class', 'message')
- if (isMessage) {
- // Current (receive) time as heading:
- const time = new Date().toLocaleTimeString()
- const h4 = document.createElement('h4')
- const h4Content = document.createTextNode(time)
- h4.appendChild(h4Content)
- div.appendChild(h4)
- }
- if (Object.keys(message).length === 0) {
+ if (Object.keys(template).length === 0) {
// Create span with '*' for empty templates:
const span = document.createElement('span')
const spanContent = document.createTextNode('*')
div.appendChild(span)
} else {
const table = document.createElement('table')
- for (const key in message) {
- if (isMessage) {
- if (key == 'sender') {
- // Ignore 'sender' for last received messages
- // (information redundantly present in client heading):
- continue
- } else if (key == 'state') {
- // Set background according to state:
- if (message[key]) {
- div.classList.add('green')
- } else {
- div.classList.add('red')
- }
- }
- }
+ for (const key in template) {
// Append table row for key-value pair:
const tr = document.createElement('tr')
const keyTd = document.createElement('td')
keyTd.appendChild(keyTdContent)
tr.appendChild(keyTd)
const valueTd = document.createElement('td')
- value = JSON.stringify(message[key])
- if (value.startsWith('"<class') && value.endsWith('>"')) {
- // Remove quotes if class type instead of literal value:
- value = value.replace(/^"|"$/g, '')
+ schema = template[key]
+ value = ''
+ if ('const' in schema) {
+ value = JSON.stringify(schema['const'])
+ } else {
+ value = JSON.stringify(schema)
}
const valueTdContent = document.createTextNode(value)
valueTd.appendChild(valueTdContent)
}
// Create form input (or select) for key-value pairs in receive templates:
-function inputsForKeyValue(key, value) {
+function inputsForKeyValue(key, schema) {
result = []
- literal = true
- if (value.match(/^<class '(str|int|float|bool)'>$/g)) {
- literal = false
+ literal = false
+ if ('const' in schema) {
+ literal = true
}
- if (value == '<class \'bool\'>' || typeof(value) == 'boolean') {
+ if (schema['type'] == 'boolean' ||
+ (literal && typeof(schema['const']) == 'boolean')) {
// Create select with true and false options for Boolean:
const select = document.createElement('select')
select.setAttribute('name', key)
if (literal) {
// Select set value and disable other value
// for literal Boolean:
- if (value) {
+ if (schema['const']) {
optionTrue.setAttribute('selected', '')
optioniFalse.setAttribute('disabled', '')
} else {
result.push(select)
} else {
// Create input for everything except Booleans:
- if (value == '<class \'str\'>' ||
- (literal && typeof(value) == 'string' && key != 'command')) {
+ if (schema['type'] == 'string' ||
+ (literal && typeof(schema['const']) == 'string' &&
+ key != 'command')) {
// Quote strings:
const openquote = document.createTextNode('"')
result.push(openquote)
// Set type of input:
if (key == 'command') {
input.setAttribute('type', 'hidden')
- } else if (value == '<class \'int\'>' || value == '<class \'float\'>' ||
- typeof(value) == 'number') {
+ } else if (schema['type'] == 'integer' ||
+ schema['type'] == 'number' ||
+ typeof(schema['const']) == 'number') {
input.setAttribute('type', 'number')
- if (value == '<class \'int\'>') {
+ if (schema['type'] == 'integer') {
input.setAttribute('step', '1')
- } else if (value == '<class \'float\'>') {
+ } else if (schema['type'] == 'number') {
input.setAttribute('step', 'any')
}
- } else if (value == '<class \'str\'>' || typeof(value) == 'string') {
+ } else if (schema['type'] == 'string' ||
+ typeof(schema['const']) == 'string') {
input.setAttribute('type', 'text')
}
// Set key as name of input:
input.setAttribute('name', key)
// Set value of input, readonly or required:
if (key == 'command') {
- input.setAttribute('value', value)
+ input.setAttribute('value', schema['const'])
} else if (literal) {
- input.setAttribute('value', value)
+ input.setAttribute('value', schema['const'])
input.setAttribute('readonly', '')
} else {
input.setAttribute('value', '')
resizeInput.call(input)
}
result.push(input)
- if (value == '<class \'str\'>' ||
- (literal && typeof(value) == 'string' && key != 'command')) {
+ if (schema['type'] == 'string' ||
+ (literal && typeof(schema['const']) == 'string' &&
+ key != 'command')) {
// Quote strings:
const closequote = document.createTextNode('"')
result.push(closequote)
// Add submit button for 'command' key:
const submit = document.createElement('input')
submit.setAttribute('type', 'submit')
- submit.setAttribute('value', value)
+ submit.setAttribute('value', schema['const'])
result.push(submit)
}
}
// Remove (if unregistered) or create (if not existent) elements for
// clients and update interface information:
function processBusMessage(message) {
- // When message is from bus:
if (message['event'] == 'unregistered') {
// On deregistration delete client element if it exists:
const clientElement = document.getElementById(message['client'])
// Crate message elements for receives interface:
const receiveContainer = document.getElementById(message['client'] + ' Receives')
receiveContainer.innerHTML = ''
- for (const template of message.receives) {
+ for (const template of message['receives']) {
if (template['command'] != null) {
receiveContainer.appendChild(createForCommand(template))
} else {
- receiveContainer.appendChild(createForMessage(template))
+ receiveContainer.appendChild(createForTemplate(template))
}
}
// Create message elements for sends interface:
const sendContainer = document.getElementById(message['client'] + ' Sends')
sendContainer.innerHTML = ''
- for (const template of message.sends) {
- sendContainer.appendChild(createForMessage(template))
+ for (const template of message['sends']) {
+ sendContainer.appendChild(createForTemplate(template))
+ }
+ }
+}
+
+// Create div and table for message:
+function createForMessage(message) {
+ const div = document.createElement('div')
+ div.setAttribute('class', 'message')
+ // Current (receive) time as heading:
+ const time = new Date().toLocaleTimeString()
+ const h4 = document.createElement('h4')
+ const h4Content = document.createTextNode(time)
+ h4.appendChild(h4Content)
+ div.appendChild(h4)
+ const table = document.createElement('table')
+ for (const key in message) {
+ if (key == 'sender') {
+ // Ignore 'sender' for last received messages
+ // (information redundantly present in client heading):
+ continue
+ } else if (key == 'state') {
+ // Set background according to state:
+ if (message[key] === true) {
+ div.classList.add('green')
+ } else if (message[key] === false) {
+ div.classList.add('red')
+ }
}
+ // Append table row for key-value pair:
+ const tr = document.createElement('tr')
+ const keyTd = document.createElement('td')
+ const keyTdContent = document.createTextNode(key + ':')
+ keyTd.appendChild(keyTdContent)
+ tr.appendChild(keyTd)
+ const valueTd = document.createElement('td')
+ value = JSON.stringify(message[key])
+ const valueTdContent = document.createTextNode(value)
+ valueTd.appendChild(valueTdContent)
+ tr.appendChild(valueTd)
+ table.appendChild(tr)
}
+ div.appendChild(table)
+ return div
}
// Create element for client (if not existent)
// Update last received message:
const lastContainer = document.getElementById(message['sender'] + ' Last')
lastContainer.innerHTML = ''
- lastContainer.appendChild(createForMessage(message, true))
+ lastContainer.appendChild(createForMessage(message))
}
// Open Websocket back to ControlPi we were loaded from: