mirror of
https://github.com/pandorafms/pandorafms.git
synced 2025-07-30 01:05:39 +02:00
WIP Visual Console Client
Former-commit-id: a638705269ea6ea35c00f1f4429c273bf861cfed
This commit is contained in:
parent
a08db7ce00
commit
589c5c97bf
@ -1,3 +1,256 @@
|
|||||||
class VisualConsole {}
|
import { UnknownObject, Size } from "./types";
|
||||||
|
import { parseBoolean, sizePropsDecoder, parseIntOr } from "./lib";
|
||||||
|
import VisualConsoleItem, {
|
||||||
|
VisualConsoleItemProps,
|
||||||
|
VisualConsoleItemType
|
||||||
|
} from "./VisualConsoleItem";
|
||||||
|
import StaticGraph, { staticGraphPropsDecoder } from "./items/StaticGraph";
|
||||||
|
import Icon, { iconPropsDecoder } from "./items/Icon";
|
||||||
|
import ColorCloud, { colorCloudPropsDecoder } from "./items/ColorCloud";
|
||||||
|
import Group, { groupPropsDecoder } from "./items/Group";
|
||||||
|
|
||||||
export default VisualConsole;
|
// Base properties.
|
||||||
|
export interface VisualConsoleProps extends Size {
|
||||||
|
readonly id: number;
|
||||||
|
name: string;
|
||||||
|
groupId: number;
|
||||||
|
backgroundURL: string | null; // URL?
|
||||||
|
backgroundColor: string | null;
|
||||||
|
isFavorite: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a valid typed object from a raw object.
|
||||||
|
* This will allow us to ensure the type safety.
|
||||||
|
*
|
||||||
|
* @param data Raw object.
|
||||||
|
* @return An object representing the Visual Console props.
|
||||||
|
* @throws Will throw a TypeError if some property
|
||||||
|
* is missing from the raw object or have an invalid type.
|
||||||
|
*/
|
||||||
|
export function visualConsolePropsDecoder(
|
||||||
|
data: UnknownObject
|
||||||
|
): VisualConsoleProps | never {
|
||||||
|
// Object destructuring: http://es6-features.org/#ObjectMatchingShorthandNotation
|
||||||
|
const {
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
groupId,
|
||||||
|
backgroundURL,
|
||||||
|
backgroundColor,
|
||||||
|
isFavorite
|
||||||
|
} = data;
|
||||||
|
|
||||||
|
if (id == null || isNaN(parseInt(id))) {
|
||||||
|
throw new TypeError("invalid Id.");
|
||||||
|
}
|
||||||
|
if (typeof name !== "string" || name.length === 0) {
|
||||||
|
throw new TypeError("invalid name.");
|
||||||
|
}
|
||||||
|
if (groupId == null || isNaN(parseInt(groupId))) {
|
||||||
|
throw new TypeError("invalid group Id.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: parseInt(id),
|
||||||
|
name,
|
||||||
|
groupId: parseInt(groupId),
|
||||||
|
backgroundURL:
|
||||||
|
typeof backgroundURL === "string" && backgroundURL.length > 0
|
||||||
|
? backgroundURL
|
||||||
|
: null,
|
||||||
|
backgroundColor:
|
||||||
|
typeof backgroundColor === "string" && backgroundColor.length > 0
|
||||||
|
? backgroundColor
|
||||||
|
: null,
|
||||||
|
isFavorite: parseBoolean(isFavorite),
|
||||||
|
...sizePropsDecoder(data)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Document.
|
||||||
|
function itemInstanceFrom(data: UnknownObject) {
|
||||||
|
const type = parseIntOr(data.type, null);
|
||||||
|
if (type == null) throw new TypeError("missing item type.");
|
||||||
|
|
||||||
|
switch (<VisualConsoleItemType>type) {
|
||||||
|
case VisualConsoleItemType.STATIC_GRAPH:
|
||||||
|
return new StaticGraph(staticGraphPropsDecoder(data));
|
||||||
|
case VisualConsoleItemType.MODULE_GRAPH:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.SIMPLE_VALUE:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.PERCENTILE_BAR:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.LABEL:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.ICON:
|
||||||
|
return new Icon(iconPropsDecoder(data));
|
||||||
|
case VisualConsoleItemType.SIMPLE_VALUE_MAX:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.SIMPLE_VALUE_MIN:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.SIMPLE_VALUE_AVG:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.PERCENTILE_BUBBLE:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.SERVICE:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.GROUP_ITEM:
|
||||||
|
return new Group(groupPropsDecoder(data));
|
||||||
|
case VisualConsoleItemType.BOX_ITEM:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.LINE_ITEM:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.AUTO_SLA_GRAPH:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.CIRCULAR_PROGRESS_BAR:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.CIRCULAR_INTERIOR_PROGRESS_BAR:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.DONUT_GRAPH:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.BARS_GRAPH:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.CLOCK:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
case VisualConsoleItemType.COLOR_CLOUD:
|
||||||
|
return new ColorCloud(colorCloudPropsDecoder(data));
|
||||||
|
default:
|
||||||
|
throw new TypeError("item not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class VisualConsole {
|
||||||
|
// Reference to the DOM element which will contain the items.
|
||||||
|
private readonly containerRef: HTMLElement;
|
||||||
|
// Properties.
|
||||||
|
private _props: VisualConsoleProps;
|
||||||
|
// Visual Console Item instances.
|
||||||
|
private elements: VisualConsoleItem<VisualConsoleItemProps>[] = [];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
container: HTMLElement,
|
||||||
|
props: VisualConsoleProps,
|
||||||
|
items: UnknownObject[]
|
||||||
|
) {
|
||||||
|
this.containerRef = container;
|
||||||
|
this._props = props;
|
||||||
|
|
||||||
|
// Force the first render.
|
||||||
|
this.render();
|
||||||
|
|
||||||
|
// TODO: Document.
|
||||||
|
items.forEach(item => {
|
||||||
|
try {
|
||||||
|
const itemInstance = itemInstanceFrom(item);
|
||||||
|
this.elements.push(itemInstance);
|
||||||
|
itemInstance.onClick(e =>
|
||||||
|
console.log(`Clicked element #${e.data.id}`, e)
|
||||||
|
);
|
||||||
|
this.containerRef.append(itemInstance.elementRef);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Error creating a new element:", error.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sort by isOnTop, id ASC
|
||||||
|
this.elements.sort(function(a, b) {
|
||||||
|
if (a.props.isOnTop && !b.props.isOnTop) return 1;
|
||||||
|
else if (!a.props.isOnTop && b.props.isOnTop) return -1;
|
||||||
|
else if (a.props.id < b.props.id) return 1;
|
||||||
|
else return -1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public accessor of the `props` property.
|
||||||
|
* @return Properties.
|
||||||
|
*/
|
||||||
|
get props(): VisualConsoleProps {
|
||||||
|
return this._props;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public setter of the `props` property.
|
||||||
|
* If the new props are different enough than the
|
||||||
|
* stored props, a render would be fired.
|
||||||
|
* @param newProps
|
||||||
|
*/
|
||||||
|
set props(newProps: VisualConsoleProps) {
|
||||||
|
const prevProps = this.props;
|
||||||
|
// Update the internal props.
|
||||||
|
this._props = newProps;
|
||||||
|
|
||||||
|
// From this point, things which rely on this.props can access to the changes.
|
||||||
|
|
||||||
|
// Re-render.
|
||||||
|
this.render(prevProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recreate or update the HTMLElement which represents the Visual Console into the DOM.
|
||||||
|
* @param prevProps If exists it will be used to only DOM updates instead of a full replace.
|
||||||
|
*/
|
||||||
|
render(prevProps: VisualConsoleProps | null = null): void {
|
||||||
|
if (prevProps) {
|
||||||
|
if (prevProps.backgroundURL !== this.props.backgroundURL) {
|
||||||
|
this.containerRef.style.backgroundImage = this.props.backgroundURL;
|
||||||
|
}
|
||||||
|
if (prevProps.backgroundColor !== this.props.backgroundColor) {
|
||||||
|
this.containerRef.style.backgroundColor = this.props.backgroundColor;
|
||||||
|
}
|
||||||
|
if (this.sizeChanged(prevProps, this.props)) {
|
||||||
|
this.resizeElement(this.props.width, this.props.height);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.containerRef.style.backgroundImage = this.props.backgroundURL;
|
||||||
|
this.containerRef.style.backgroundColor = this.props.backgroundColor;
|
||||||
|
this.resizeElement(this.props.width, this.props.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the previous and the new size and return
|
||||||
|
* a boolean value in case the size changed.
|
||||||
|
* @param prevSize
|
||||||
|
* @param newSize
|
||||||
|
* @return Whether the size changed or not.
|
||||||
|
*/
|
||||||
|
sizeChanged(prevSize: Size, newSize: Size): boolean {
|
||||||
|
return (
|
||||||
|
prevSize.width !== newSize.width || prevSize.height !== newSize.height
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resize the DOM container.
|
||||||
|
* @param width
|
||||||
|
* @param height
|
||||||
|
*/
|
||||||
|
resizeElement(width: number, height: number): void {
|
||||||
|
this.containerRef.style.width = `${width}px`;
|
||||||
|
this.containerRef.style.height = `${height}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the size into the properties and resize the DOM container.
|
||||||
|
* @param width
|
||||||
|
* @param height
|
||||||
|
*/
|
||||||
|
resize(width: number, height: number): void {
|
||||||
|
this.props = {
|
||||||
|
...this.props, // Object spread: http://es6-features.org/#SpreadOperator
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To remove the event listeners and the elements from the DOM.
|
||||||
|
*/
|
||||||
|
remove(): void {
|
||||||
|
this.elements.forEach(e => e.remove()); // Arrow function.
|
||||||
|
this.elements = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -7,19 +7,63 @@ import {
|
|||||||
} from "./lib";
|
} from "./lib";
|
||||||
import TypedEvent, { Listener, Disposable } from "./TypedEvent";
|
import TypedEvent, { Listener, Disposable } from "./TypedEvent";
|
||||||
|
|
||||||
|
// Enum: https://www.typescriptlang.org/docs/handbook/enums.html.
|
||||||
|
export const enum VisualConsoleItemType {
|
||||||
|
STATIC_GRAPH = 0,
|
||||||
|
MODULE_GRAPH = 1,
|
||||||
|
SIMPLE_VALUE = 2,
|
||||||
|
PERCENTILE_BAR = 3,
|
||||||
|
LABEL = 4,
|
||||||
|
ICON = 5,
|
||||||
|
SIMPLE_VALUE_MAX = 6,
|
||||||
|
SIMPLE_VALUE_MIN = 7,
|
||||||
|
SIMPLE_VALUE_AVG = 8,
|
||||||
|
PERCENTILE_BUBBLE = 9,
|
||||||
|
SERVICE = 10,
|
||||||
|
GROUP_ITEM = 11,
|
||||||
|
BOX_ITEM = 12,
|
||||||
|
LINE_ITEM = 13,
|
||||||
|
AUTO_SLA_GRAPH = 14,
|
||||||
|
CIRCULAR_PROGRESS_BAR = 15,
|
||||||
|
CIRCULAR_INTERIOR_PROGRESS_BAR = 16,
|
||||||
|
DONUT_GRAPH = 17,
|
||||||
|
BARS_GRAPH = 18,
|
||||||
|
CLOCK = 19,
|
||||||
|
COLOR_CLOUD = 20
|
||||||
|
}
|
||||||
|
|
||||||
// Base item properties. This interface should be extended by the item implementations.
|
// Base item properties. This interface should be extended by the item implementations.
|
||||||
export interface VisualConsoleItemProps extends Position, Size {
|
export interface VisualConsoleItemProps extends Position, Size {
|
||||||
readonly id: number;
|
readonly id: number;
|
||||||
readonly type: number;
|
readonly type: VisualConsoleItemType;
|
||||||
label: string | null;
|
label: string | null;
|
||||||
|
labelPosition: "up" | "right" | "down" | "left";
|
||||||
isLinkEnabled: boolean;
|
isLinkEnabled: boolean;
|
||||||
isOnTop: boolean;
|
isOnTop: boolean;
|
||||||
parentId: number | null;
|
parentId: number | null;
|
||||||
aclGroupId: number | null;
|
aclGroupId: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Fix type compatibility.
|
||||||
export type ItemClickEvent<ItemProps extends VisualConsoleItemProps> = {
|
export type ItemClickEvent<ItemProps extends VisualConsoleItemProps> = {
|
||||||
data: ItemProps;
|
// data: ItemProps;
|
||||||
|
data: UnknownObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract a valid enum value from a raw label position value.
|
||||||
|
* @param labelPosition Raw value.
|
||||||
|
*/
|
||||||
|
const parseLabelPosition = (labelPosition: any) => {
|
||||||
|
switch (labelPosition) {
|
||||||
|
case "up":
|
||||||
|
case "right":
|
||||||
|
case "down":
|
||||||
|
case "left":
|
||||||
|
return labelPosition;
|
||||||
|
default:
|
||||||
|
return "down";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,13 +75,13 @@ export type ItemClickEvent<ItemProps extends VisualConsoleItemProps> = {
|
|||||||
* @throws Will throw a TypeError if some property
|
* @throws Will throw a TypeError if some property
|
||||||
* is missing from the raw object or have an invalid type.
|
* is missing from the raw object or have an invalid type.
|
||||||
*/
|
*/
|
||||||
export function itemPropsDecoder(
|
export function itemBasePropsDecoder(
|
||||||
data: UnknownObject
|
data: UnknownObject
|
||||||
): VisualConsoleItemProps | never {
|
): VisualConsoleItemProps | never {
|
||||||
if (data.id == null || isNaN(parseInt(data.id))) {
|
if (data.id == null || isNaN(parseInt(data.id))) {
|
||||||
throw new TypeError("invalid id.");
|
throw new TypeError("invalid id.");
|
||||||
}
|
}
|
||||||
// TODO: Check valid types.
|
// TODO: Check for valid types.
|
||||||
if (data.type == null || isNaN(parseInt(data.type))) {
|
if (data.type == null || isNaN(parseInt(data.type))) {
|
||||||
throw new TypeError("invalid type.");
|
throw new TypeError("invalid type.");
|
||||||
}
|
}
|
||||||
@ -49,6 +93,7 @@ export function itemPropsDecoder(
|
|||||||
typeof data.label === "string" && data.label.length > 0
|
typeof data.label === "string" && data.label.length > 0
|
||||||
? data.label
|
? data.label
|
||||||
: null,
|
: null,
|
||||||
|
labelPosition: parseLabelPosition(data.labelPosition),
|
||||||
isLinkEnabled: parseBoolean(data.isLinkEnabled),
|
isLinkEnabled: parseBoolean(data.isLinkEnabled),
|
||||||
isOnTop: parseBoolean(data.isOnTop),
|
isOnTop: parseBoolean(data.isOnTop),
|
||||||
parentId: parseIntOr(data.parentId, null),
|
parentId: parseIntOr(data.parentId, null),
|
||||||
@ -61,12 +106,10 @@ export function itemPropsDecoder(
|
|||||||
abstract class VisualConsoleItem<ItemProps extends VisualConsoleItemProps> {
|
abstract class VisualConsoleItem<ItemProps extends VisualConsoleItemProps> {
|
||||||
// Properties of the item.
|
// Properties of the item.
|
||||||
private itemProps: ItemProps;
|
private itemProps: ItemProps;
|
||||||
// Reference of the DOM element which contain all the items.
|
// Reference to the DOM element which will contain the item.
|
||||||
private readonly containerRef: HTMLElement;
|
public readonly elementRef: HTMLElement;
|
||||||
// Reference of the DOM element which contain the item box.
|
// Reference to the DOM element which will contain the view of the item which extends this class.
|
||||||
private readonly itemBoxRef: HTMLElement;
|
protected readonly childElementRef: HTMLElement;
|
||||||
// Reference of the DOM element which contain the view of the item which extends this class.
|
|
||||||
protected readonly elementRef: HTMLElement;
|
|
||||||
// Event manager for click events.
|
// Event manager for click events.
|
||||||
private readonly clickEventManager = new TypedEvent<
|
private readonly clickEventManager = new TypedEvent<
|
||||||
ItemClickEvent<ItemProps>
|
ItemClickEvent<ItemProps>
|
||||||
@ -80,8 +123,7 @@ abstract class VisualConsoleItem<ItemProps extends VisualConsoleItemProps> {
|
|||||||
*/
|
*/
|
||||||
abstract createDomElement(): HTMLElement;
|
abstract createDomElement(): HTMLElement;
|
||||||
|
|
||||||
constructor(container: HTMLElement, props: ItemProps) {
|
constructor(props: ItemProps) {
|
||||||
this.containerRef = container;
|
|
||||||
this.itemProps = props;
|
this.itemProps = props;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -90,30 +132,31 @@ abstract class VisualConsoleItem<ItemProps extends VisualConsoleItemProps> {
|
|||||||
* all the common things like click events, show a border
|
* all the common things like click events, show a border
|
||||||
* when hovered, etc.
|
* when hovered, etc.
|
||||||
*/
|
*/
|
||||||
this.itemBoxRef = this.createItemBoxDomElement();
|
this.elementRef = this.createContainerDomElement();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a HTMLElement which represents the custom view
|
* Get a HTMLElement which represents the custom view
|
||||||
* of the Visual Console item. This element will be
|
* of the Visual Console item. This element will be
|
||||||
* different depending on the item implementation.
|
* different depending on the item implementation.
|
||||||
*/
|
*/
|
||||||
this.elementRef = this.createDomElement();
|
this.childElementRef = this.createDomElement();
|
||||||
|
|
||||||
// Insert the elements into their parents.
|
// Insert the elements into the container.
|
||||||
// Visual Console Container > Generic Item Box > Custom Item View.
|
// Visual Console Item Container > Custom Item View.
|
||||||
this.itemBoxRef.append(this.elementRef);
|
this.elementRef.append(this.childElementRef);
|
||||||
this.containerRef.append(this.itemBoxRef);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To create a new box for the visual console item.
|
* To create a new box for the visual console item.
|
||||||
* @return Item box.
|
* @return Item box.
|
||||||
*/
|
*/
|
||||||
private createItemBoxDomElement(): HTMLElement {
|
private createContainerDomElement(): HTMLElement {
|
||||||
const box: HTMLDivElement = document.createElement("div");
|
const box: HTMLDivElement = document.createElement("div");
|
||||||
box.className = "visual-console-item";
|
box.className = "visual-console-item";
|
||||||
box.style.width = `${this.props.width}px`;
|
box.style.width = `${this.props.width}px`;
|
||||||
box.style.height = `${this.props.height}px`;
|
box.style.height = `${this.props.height}px`;
|
||||||
|
box.style.left = `${this.props.x}px`;
|
||||||
|
box.style.top = `${this.props.y}px`;
|
||||||
box.onclick = () => this.clickEventManager.emit({ data: this.props });
|
box.onclick = () => this.clickEventManager.emit({ data: this.props });
|
||||||
// TODO: Add label.
|
// TODO: Add label.
|
||||||
return box;
|
return box;
|
||||||
@ -161,26 +204,25 @@ abstract class VisualConsoleItem<ItemProps extends VisualConsoleItemProps> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* To recreate or update the HTMLElement which represents the item into the DOM.
|
* To recreate or update the HTMLElement which represents the item into the DOM.
|
||||||
* @param prevProps If exists it will be used to only perform
|
* @param prevProps If exists it will be used to only perform DOM updates instead of a full replace.
|
||||||
* perform DOM updates instead of a full replace.
|
|
||||||
*/
|
*/
|
||||||
render(prevProps: ItemProps | null): void {
|
render(prevProps: ItemProps | null = null): void {
|
||||||
// Move box.
|
// Move box.
|
||||||
if (!prevProps || prevProps.x !== this.props.x) {
|
if (!prevProps || prevProps.x !== this.props.x) {
|
||||||
this.itemBoxRef.style.left = `${this.props.x}px`;
|
this.elementRef.style.left = `${this.props.x}px`;
|
||||||
}
|
}
|
||||||
if (!prevProps || prevProps.y !== this.props.y) {
|
if (!prevProps || prevProps.y !== this.props.y) {
|
||||||
this.itemBoxRef.style.top = `${this.props.y}px`;
|
this.elementRef.style.top = `${this.props.y}px`;
|
||||||
}
|
}
|
||||||
// Resize box.
|
// Resize box.
|
||||||
if (!prevProps || prevProps.width !== this.props.width) {
|
if (!prevProps || prevProps.width !== this.props.width) {
|
||||||
this.itemBoxRef.style.width = `${this.props.width}px`;
|
this.elementRef.style.width = `${this.props.width}px`;
|
||||||
}
|
}
|
||||||
if (!prevProps || prevProps.height !== this.props.height) {
|
if (!prevProps || prevProps.height !== this.props.height) {
|
||||||
this.itemBoxRef.style.height = `${this.props.height}px`;
|
this.elementRef.style.height = `${this.props.height}px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.elementRef.replaceWith(this.createDomElement());
|
this.childElementRef.replaceWith(this.createDomElement());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -190,9 +232,9 @@ abstract class VisualConsoleItem<ItemProps extends VisualConsoleItemProps> {
|
|||||||
// Event listeners.
|
// Event listeners.
|
||||||
this.disposables.forEach(_ => _.dispose());
|
this.disposables.forEach(_ => _.dispose());
|
||||||
// VisualConsoleItem extension DOM element.
|
// VisualConsoleItem extension DOM element.
|
||||||
this.elementRef.remove();
|
this.childElementRef.remove();
|
||||||
// VisualConsoleItem DOM element.
|
// VisualConsoleItem DOM element.
|
||||||
this.itemBoxRef.remove();
|
this.elementRef.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -207,8 +249,8 @@ abstract class VisualConsoleItem<ItemProps extends VisualConsoleItemProps> {
|
|||||||
this.itemProps.x = x;
|
this.itemProps.x = x;
|
||||||
this.itemProps.y = y;
|
this.itemProps.y = y;
|
||||||
// Move element.
|
// Move element.
|
||||||
this.itemBoxRef.style.left = `${x}px`;
|
this.elementRef.style.left = `${x}px`;
|
||||||
this.itemBoxRef.style.top = `${y}px`;
|
this.elementRef.style.top = `${y}px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -223,8 +265,8 @@ abstract class VisualConsoleItem<ItemProps extends VisualConsoleItemProps> {
|
|||||||
this.itemProps.width = width;
|
this.itemProps.width = width;
|
||||||
this.itemProps.height = height;
|
this.itemProps.height = height;
|
||||||
// Resize element.
|
// Resize element.
|
||||||
this.itemBoxRef.style.width = `${width}px`;
|
this.elementRef.style.width = `${width}px`;
|
||||||
this.itemBoxRef.style.height = `${height}px`;
|
this.elementRef.style.height = `${height}px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
// import VisualConsole from "./VisualConsole";
|
/*
|
||||||
import StaticGraphItem from "./items/StaticGraph";
|
* Useful resources.
|
||||||
|
* http://es6-features.org/
|
||||||
|
* http://exploringjs.com/es6
|
||||||
|
* https://www.typescriptlang.org/
|
||||||
|
*/
|
||||||
|
|
||||||
|
import VisualConsole, {
|
||||||
|
visualConsolePropsDecoder,
|
||||||
|
VisualConsoleProps
|
||||||
|
} from "./VisualConsole";
|
||||||
|
|
||||||
// declare global {
|
// declare global {
|
||||||
// interface Window {
|
// interface Window {
|
||||||
@ -12,21 +21,32 @@ import StaticGraphItem from "./items/StaticGraph";
|
|||||||
const container = document.getElementById("visual-console-container");
|
const container = document.getElementById("visual-console-container");
|
||||||
|
|
||||||
if (container != null) {
|
if (container != null) {
|
||||||
const item = new StaticGraphItem(container, {
|
const rawProps = {
|
||||||
|
id: 1,
|
||||||
|
groupId: 0,
|
||||||
|
name: "Test Visual Console",
|
||||||
|
width: 800,
|
||||||
|
height: 300,
|
||||||
|
backgroundURL: null,
|
||||||
|
backgroundColor: "#000000",
|
||||||
|
isFavorite: false
|
||||||
|
};
|
||||||
|
|
||||||
|
const staticGraphRawProps = {
|
||||||
// Generic props.
|
// Generic props.
|
||||||
id: 1,
|
id: 1,
|
||||||
type: 1,
|
type: 0, // Static graph = 0
|
||||||
label: null,
|
label: null,
|
||||||
isLinkEnabled: false,
|
isLinkEnabled: false,
|
||||||
isOnTop: false,
|
isOnTop: false,
|
||||||
parentId: null,
|
parentId: null,
|
||||||
aclGroupId: null,
|
aclGroupId: null,
|
||||||
// Position props.
|
// Position props.
|
||||||
x: 0,
|
x: 100,
|
||||||
y: 0,
|
y: 50,
|
||||||
// Size props.
|
// Size props.
|
||||||
width: 50,
|
width: 100,
|
||||||
height: 50,
|
height: 100,
|
||||||
// Agent props.
|
// Agent props.
|
||||||
agentId: null,
|
agentId: null,
|
||||||
agentName: null,
|
agentName: null,
|
||||||
@ -37,5 +57,42 @@ if (container != null) {
|
|||||||
imageSrc:
|
imageSrc:
|
||||||
"https://brutus.artica.lan:8081/uploads/-/system/project/avatar/1/1.png",
|
"https://brutus.artica.lan:8081/uploads/-/system/project/avatar/1/1.png",
|
||||||
showLastValueTooltip: "default"
|
showLastValueTooltip: "default"
|
||||||
});
|
};
|
||||||
|
|
||||||
|
const colorCloudRawProps = {
|
||||||
|
// Generic props.
|
||||||
|
id: 2,
|
||||||
|
type: 20, // Static graph = 0
|
||||||
|
label: null,
|
||||||
|
labelText: "CLOUD",
|
||||||
|
isLinkEnabled: false,
|
||||||
|
isOnTop: false,
|
||||||
|
parentId: null,
|
||||||
|
aclGroupId: null,
|
||||||
|
// Position props.
|
||||||
|
x: 300,
|
||||||
|
y: 50,
|
||||||
|
// Size props.
|
||||||
|
width: 150,
|
||||||
|
height: 150,
|
||||||
|
// Agent props.
|
||||||
|
agentId: null,
|
||||||
|
agentName: null,
|
||||||
|
// Module props.
|
||||||
|
moduleId: null,
|
||||||
|
moduleName: null,
|
||||||
|
// Custom props.
|
||||||
|
color: "rgb(100, 50, 245)"
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const visualConsole = new VisualConsole(
|
||||||
|
container,
|
||||||
|
visualConsolePropsDecoder(rawProps),
|
||||||
|
[staticGraphRawProps, colorCloudRawProps]
|
||||||
|
);
|
||||||
|
console.log(visualConsole);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("ERROR", error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,16 @@ import {
|
|||||||
UnknownObject
|
UnknownObject
|
||||||
} from "../types";
|
} from "../types";
|
||||||
|
|
||||||
import { modulePropsDecoder } from "../lib";
|
import { modulePropsDecoder, linkedVCPropsDecoder } from "../lib";
|
||||||
|
|
||||||
import VisualConsoleItem, {
|
import VisualConsoleItem, {
|
||||||
VisualConsoleItemProps,
|
VisualConsoleItemProps,
|
||||||
itemPropsDecoder
|
itemBasePropsDecoder,
|
||||||
|
VisualConsoleItemType
|
||||||
} from "../VisualConsoleItem";
|
} from "../VisualConsoleItem";
|
||||||
|
|
||||||
export type StaticGraphProps = {
|
export type StaticGraphProps = {
|
||||||
|
type: VisualConsoleItemType.STATIC_GRAPH;
|
||||||
imageSrc: string; // URL?
|
imageSrc: string; // URL?
|
||||||
showLastValueTooltip: "default" | "enabled" | "disabled";
|
showLastValueTooltip: "default" | "enabled" | "disabled";
|
||||||
} & VisualConsoleItemProps &
|
} & VisualConsoleItemProps &
|
||||||
@ -49,10 +51,12 @@ export function staticGraphPropsDecoder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.
|
||||||
|
type: VisualConsoleItemType.STATIC_GRAPH,
|
||||||
imageSrc: data.imageSrc,
|
imageSrc: data.imageSrc,
|
||||||
showLastValueTooltip: parseShowLastValueTooltip(data.showLastValueTooltip),
|
showLastValueTooltip: parseShowLastValueTooltip(data.showLastValueTooltip),
|
||||||
...itemPropsDecoder(data), // Object spread. It will merge the properties of the two objects.
|
...modulePropsDecoder(data), // Object spread. It will merge the properties of the two objects.
|
||||||
...modulePropsDecoder(data) // Object spread. It will merge the properties of the two objects.
|
...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,6 +66,8 @@ export default class StaticGraph extends VisualConsoleItem<StaticGraphProps> {
|
|||||||
img.className = "static-graph";
|
img.className = "static-graph";
|
||||||
img.src = this.props.imageSrc;
|
img.src = this.props.imageSrc;
|
||||||
|
|
||||||
|
// TODO: Show last value in a tooltip.
|
||||||
|
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ export function sizePropsDecoder(data: UnknownObject): Size | never {
|
|||||||
* @return An object representing the agent properties.
|
* @return An object representing the agent properties.
|
||||||
*/
|
*/
|
||||||
export function agentPropsDecoder(data: UnknownObject): WithAgentProps {
|
export function agentPropsDecoder(data: UnknownObject): WithAgentProps {
|
||||||
// Object destructuring: http://exploringjs.com/es6/ch_destructuring.html
|
// Object destructuring: http://es6-features.org/#ObjectMatchingShorthandNotation
|
||||||
const { metaconsoleId, agentId: id, agentName: name } = data;
|
const { metaconsoleId, agentId: id, agentName: name } = data;
|
||||||
|
|
||||||
const agentProps: WithAgentProps = {
|
const agentProps: WithAgentProps = {
|
||||||
@ -84,7 +84,7 @@ export function agentPropsDecoder(data: UnknownObject): WithAgentProps {
|
|||||||
return metaconsoleId != null
|
return metaconsoleId != null
|
||||||
? {
|
? {
|
||||||
metaconsoleId,
|
metaconsoleId,
|
||||||
...agentProps // Object spread: http://exploringjs.com/es6/ch_parameter-handling.html#sec_spread-operator
|
...agentProps // Object spread: http://es6-features.org/#SpreadOperator
|
||||||
}
|
}
|
||||||
: agentProps;
|
: agentProps;
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ export function agentPropsDecoder(data: UnknownObject): WithAgentProps {
|
|||||||
* @return An object representing the module and agent properties.
|
* @return An object representing the module and agent properties.
|
||||||
*/
|
*/
|
||||||
export function modulePropsDecoder(data: UnknownObject): WithModuleProps {
|
export function modulePropsDecoder(data: UnknownObject): WithModuleProps {
|
||||||
// Object destructuring: http://exploringjs.com/es6/ch_destructuring.html
|
// Object destructuring: http://es6-features.org/#ObjectMatchingShorthandNotation
|
||||||
const { moduleId: id, moduleName: name } = data;
|
const { moduleId: id, moduleName: name } = data;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -114,7 +114,7 @@ export function modulePropsDecoder(data: UnknownObject): WithModuleProps {
|
|||||||
export function linkedVCPropsDecoder(
|
export function linkedVCPropsDecoder(
|
||||||
data: UnknownObject
|
data: UnknownObject
|
||||||
): LinkedVisualConsoleProps | never {
|
): LinkedVisualConsoleProps | never {
|
||||||
// Object destructuring: http://exploringjs.com/es6/ch_destructuring.html
|
// Object destructuring: http://es6-features.org/#ObjectMatchingShorthandNotation
|
||||||
const {
|
const {
|
||||||
metaconsoleId,
|
metaconsoleId,
|
||||||
linkedLayoutId: id,
|
linkedLayoutId: id,
|
||||||
@ -160,13 +160,13 @@ export function linkedVCPropsDecoder(
|
|||||||
const linkedLayoutBaseProps = {
|
const linkedLayoutBaseProps = {
|
||||||
linkedLayoutId: parseIntOr(id, null),
|
linkedLayoutId: parseIntOr(id, null),
|
||||||
linkedLayoutAgentId: parseIntOr(agentId, null),
|
linkedLayoutAgentId: parseIntOr(agentId, null),
|
||||||
...linkedLayoutStatusProps // Object spread: http://exploringjs.com/es6/ch_parameter-handling.html#sec_spread-operator
|
...linkedLayoutStatusProps // Object spread: http://es6-features.org/#SpreadOperator
|
||||||
};
|
};
|
||||||
|
|
||||||
return metaconsoleId != null
|
return metaconsoleId != null
|
||||||
? {
|
? {
|
||||||
metaconsoleId,
|
metaconsoleId,
|
||||||
...linkedLayoutBaseProps // Object spread: http://exploringjs.com/es6/ch_parameter-handling.html#sec_spread-operator
|
...linkedLayoutBaseProps // Object spread: http://es6-features.org/#SpreadOperator
|
||||||
}
|
}
|
||||||
: linkedLayoutBaseProps;
|
: linkedLayoutBaseProps;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
.visual-console-item {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
.visual-console-item > * {
|
.visual-console-item > * {
|
||||||
width: inherit;
|
width: inherit;
|
||||||
height: inherit;
|
height: inherit;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user