Commit 2878efac authored by StreatCodes's avatar StreatCodes
Browse files

Add ImageCheck

Refactor code
Improve naming consistency
Initial work for SVG check
parent 77a5b318
import { h, Fragment } from 'preact';
import { useState, useEffect } from 'preact/hooks';
import { CardOptionFields } from './elements/card';
import { CheckCardOptions } from './elements/card';
import { CheckImageOptions } from './elements/image';
import { routeParam, removeParam } from './util';
import { route } from 'preact-router';
import * as meerkat from './meerkat';
......@@ -80,11 +81,10 @@ export function CheckSettings({selectedCheck, updateCheck}) {
updateCheck({...selectedCheck, options: newOptions})
}
const checkTypeOptions = {
'card': <CardOptionFields updateOptions={updateCheckOptions} check={selectedCheck} />,
'svg': <div>svg options</div>,
'image': <div>image options</div>
}
let checkOptions = null;
if(selectedCheck.type === 'card') { checkOptions = <CheckCardOptions updateOptions={updateCheckOptions} check={selectedCheck} /> }
// if(selectedCheck.type === 'svg') { checkOptions = <CheckSVGOptions updateOptions={updateCheckOptions} options={check.options}/> }
if(selectedCheck.type === 'image') { checkOptions = <CheckImageOptions updateOptions={updateCheckOptions} options={selectedCheck}/> }
return <div class="editor settings-overlay">
<div class="options">
......@@ -111,7 +111,7 @@ export function CheckSettings({selectedCheck, updateCheck}) {
<IcingaCheckList check={selectedCheck}
updateCheckID={checkID => updateCheck({...selectedCheck, checkID: checkID})} />
{checkTypeOptions[selectedCheck.type]}
{checkOptions}
</div>
</div>
</div>
......
......@@ -5,7 +5,8 @@ import { useEffect, useReducer } from 'preact/hooks';
import * as meerkat from './meerkat'
import { SidePanelChecks, CheckSettings } from './check-settings';
import { SidePanelStatics, StaticSettings } from './static-settings';
import { CardElement } from './elements/card';
import { CheckCard } from './elements/card';
import { CheckImage } from './elements/image';
import { removeParam } from './util';
import { StaticText } from './statics/text';
import { StaticSVG } from './statics/svg';
......@@ -247,13 +248,10 @@ function DashboardChecks({dashboardDispatch, selectedCheckId, checks}) {
});
}
let element = <CardElement check={check} />
if(check.type === 'svg') {
element = <div> todo </div>
}
if(check.type === 'image') {
element = <div> todo </div>
}
let element = null;
if(check.type === 'card') { element = <CheckCard check={check} /> }
if(check.type === 'svg') { element = <CheckSVG check={check}/> }
if(check.type === 'image') { element = <CheckImage check={check}/> }
return <TransformableElement rect={check.rect} updateRect={updateRect}
glow={selectedCheckId === index}>
......
......@@ -2,44 +2,18 @@ import { h } from 'preact';
import { useState, useEffect } from 'preact/hooks';
import * as meerkat from '../meerkat';
// Value Host State Service State
// 0 Up OK
// 1 Up Warning
// 2 Down Critical
// 3 Down Unknown
//icinga state matrix: states[type][state]
const states = {
service: {
0: 'ok',
1: 'warning',
2: 'critical',
3: 'unknown'
},
host: {
0: 'up',
1: 'up',
2: 'down',
3: 'down'
}
}
const checkType = (checkID) => checkID.includes('!') ? 'service' : 'host';
import { icingaResultCodeToCheckState, icingaCheckTypeFromId } from '../util'
//The rendered view (in the actual dashboard) of the Card Element
export function CardElement({check}) {
export function CheckCard({check}) {
const [checkState, setCheckState] = useState(null);
//Handle state update
const updateState = () => {
const id = check.checkID;
const t = checkType(id);
meerkat.getIcingaCheckState(id, t).then(res => {
const state = states[t][res[0].state];
setCheckState(state);
});
const updateState = async () => {
const checkType = icingaCheckTypeFromId(check.checkID);
const res = await meerkat.getIcingaCheckState(check.checkID, checkType);
const state = icingaResultCodeToCheckState(checkType, res.state);
setCheckState(state);
}
//Setup check refresher
......@@ -60,7 +34,7 @@ export function CardElement({check}) {
}
//Card options, displayed in the sidebar
export function CardOptionFields({check, updateOptions}) {
export function CheckCardOptions({check, updateOptions}) {
return <div class="card-options">
<label for="name-font-size">Name Font Size</label>
<input id="name-font-size" name="name-font-size" type="number" min="0"
......
import { h, Fragment } from 'preact';
import { useState, useEffect } from 'preact/hooks';
import * as meerkat from '../meerkat';
import { icingaResultCodeToCheckState, icingaCheckTypeFromId } from '../util'
export function CheckImageOptions({options, updateOptions}) {
const handleImageUpload = async (fieldName, files) => {
const res = await meerkat.uploadFile(files[0]);
const opts = {}
opts[fieldName] = res.url
updateOptions(opts);
}
return <Fragment>
<label for="ok-image">OK State Image</label>
<input id="ok-image" name="ok-image" type="file"
accept="image/*" onInput={e => handleImageUpload('okImage', e.target.files)}/>
<label for="warning-image">Warning State Image</label>
<input id="warning-image" name="warning-image" type="file"
accept="image/*" onInput={e => handleImageUpload('warningImage', e.target.files)}/>
<label for="unknown-image">Unknown State Image</label>
<input id="unknown-image" name="unknown-image" type="file"
accept="image/*" onInput={e => handleImageUpload('unknownImage', e.target.files)}/>
<label for="critical-image">Critical State Image</label>
<input id="critical-image" name="critical-image" type="file"
accept="image/*" onInput={e => handleImageUpload('criticalImage', e.target.files)}/>
</Fragment>
}
//The rendered view (in the actual dashboard) of the Check Image
export function CheckImage({check}) {
const [checkState, setCheckState] = useState(null);
//Handle state update
const updateState = async () => {
const checkType = icingaCheckTypeFromId(check.checkID);
const res = await meerkat.getIcingaCheckState(check.checkID, checkType);
const state = icingaResultCodeToCheckState(checkType, res.state);
setCheckState(state);
}
//Setup check refresher
useEffect(() => {
if(check.checkID !== null) {
updateState();
const intervalID = window.setInterval(updateState, 30*1000)
return () => window.clearInterval(intervalID);
}
}, [check.checkID]);
let source = null;
if(checkState === 'ok' || checkState === 'up') {source = check.options.okImage}
if(checkState === 'warning') {source = check.options.warningImage}
if(checkState === 'unknown') {source = check.options.unknownImage}
if(checkState === 'critical' || checkState === 'down') {source = check.options.criticalImage}
return <div class="check-content image">
<img src={source} />
</div>
}
\ No newline at end of file
import { h, Fragment } from 'preact';
import { useState, useEffect } from 'preact/hooks';
import * as meerkat from '../meerkat';
import { icingaResultCodeToCheckState, icingaCheckTypeFromId } from '../util'
export function CheckSVGOptions({options, updateOptions}) {
return <div>todo</div>
}
//The rendered view (in the actual dashboard) of the Check SVG
export function CheckSVG({check}) {
const [checkState, setCheckState] = useState(null);
//Handle state update
const updateState = async () => {
const checkType = icingaCheckTypeFromId(check.checkID);
const res = await meerkat.getIcingaCheckState(check.checkID, checkType);
const state = icingaResultCodeToCheckState(checkType, res.state);
setCheckState(state);
}
//Setup check refresher
useEffect(() => {
if(check.checkID !== null) {
updateState();
const intervalID = window.setInterval(updateState, 30*1000)
return () => window.clearInterval(intervalID);
}
}, [check.checkID]);
// let source = null;
// if(checkState === 'ok' || checkState === 'up') {source = check.options.okImage}
// if(checkState === 'warning') {source = check.options.warningImage}
// if(checkState === 'unknown') {source = check.options.unknownImage}
// if(checkState === 'critical' || checkState === 'down') {source = check.options.criticalImage}
return <div class="check-content svg">TODO</div>
}
\ No newline at end of file
......@@ -12,7 +12,11 @@ export async function getIcingaServices() {
export async function getIcingaCheckState(checkId, checkType) {
const res = await fetch(`/icinga/${checkType}s/${encodeURIComponent(checkId)}`);
return res.json();
const data = await res.json();
if(data.length < 1) {
throw new Error('Expected atleast one result in icinga check response');
}
return data[0];
}
export async function getAllDashboards() {
......
......@@ -20,4 +20,32 @@ export function removeParam(name) {
} else {
route(`${window.location.pathname}?${params}`);
}
}
export function icingaCheckTypeFromId(checkId) {
if(checkId.includes('!')) {
return 'service';
} else {
return 'host';
}
}
export function icingaResultCodeToCheckState(checkType, resultCode) {
if(checkType === 'service') {
switch(resultCode){
case 0: return 'ok';
case 1: return 'warning';
case 2: return 'critical';
case 3: return 'unknown';
}
} else if(checkType === 'host') {
switch(resultCode){
case 0: return 'up';
case 1: return 'up';
case 2: return 'down';
case 3: return 'down';
}
}
return 'invalid'
}
\ No newline at end of file
......@@ -3,7 +3,9 @@ import { route } from 'preact-router';
import { useState, useEffect } from 'preact/hooks';
import * as meerkat from './meerkat';
import { CardElement } from './elements/card';
import { CheckCard } from './elements/card';
import { CheckImage } from './elements/image';
import { CheckSVG } from './elements/svg';
import { StaticText } from './statics/text';
import { StaticSVG } from './statics/svg';
......@@ -27,8 +29,13 @@ export function Viewer({slug}) {
const width = `${check.rect.w}%`;
const height = `${check.rect.h}%`;
let element = null;
if(check.type === 'card') { element = <CheckCard check={check}/> }
if(check.type === 'svg') { element = <CheckSVG check={check}/> }
if(check.type === 'image') { element = <CheckImage check={check}/> }
return <div class="check" style={{left: left, top: top, width: width, height: height}}>
<CardElement check={check} />
{element}
</div>
});
......
......@@ -490,6 +490,7 @@ div.side-bar-footer {
padding: 20px;
background-color: var(--color-light-gray);
min-width: 380px;
border-top: solid 1px #aaa;
}
/* DASHBOARD ELEMENTS */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment