diff --git a/visual_console/playground/index.html b/visual_console/playground/index.html
index 3705f568ac..b6dcd0574b 100644
--- a/visual_console/playground/index.html
+++ b/visual_console/playground/index.html
@@ -150,12 +150,29 @@
showClockTimezone: true
};
+ var boxRawProps = {
+ // Generic props.
+ id: 6,
+ type: 12, // Box = 12
+ // Position props.
+ x: 720,
+ y: 20,
+ // Size props.
+ width: 50,
+ height: 50,
+ // Custom props.
+ borderWidth: 10,
+ borderColor: "white",
+ fillColor: "black"
+ };
+
var items = [
staticGraphRawProps,
colorCloudRawProps,
digitalClockRawProps,
digitalClockRawProps2,
- analogicClockRawProps
+ analogicClockRawProps,
+ boxRawProps
];
try {
diff --git a/visual_console/src/VisualConsole.ts b/visual_console/src/VisualConsole.ts
index 3472ea008e..14f94aac42 100644
--- a/visual_console/src/VisualConsole.ts
+++ b/visual_console/src/VisualConsole.ts
@@ -1,14 +1,17 @@
import { UnknownObject, Size } from "./types";
-import { parseBoolean, sizePropsDecoder, parseIntOr } from "./lib";
-import VisualConsoleItem, {
- VisualConsoleItemProps,
- VisualConsoleItemType
-} from "./VisualConsoleItem";
+import {
+ parseBoolean,
+ sizePropsDecoder,
+ parseIntOr,
+ notEmptyStringOr
+} from "./lib";
+import Item, { ItemType, ItemProps } from "./Item";
import StaticGraph, { staticGraphPropsDecoder } from "./items/StaticGraph";
import Icon, { iconPropsDecoder } from "./items/Icon";
import ColorCloud, { colorCloudPropsDecoder } from "./items/ColorCloud";
import Group, { groupPropsDecoder } from "./items/Group";
import Clock, { clockPropsDecoder } from "./items/Clock";
+import Box, { boxPropsDecoder } from "./items/Box";
// Base properties.
export interface VisualConsoleProps extends Size {
@@ -56,14 +59,8 @@ export function visualConsolePropsDecoder(
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,
+ backgroundURL: notEmptyStringOr(backgroundURL, null),
+ backgroundColor: notEmptyStringOr(backgroundColor, null),
isFavorite: parseBoolean(isFavorite),
...sizePropsDecoder(data)
};
@@ -75,48 +72,48 @@ function itemInstanceFrom(data: UnknownObject) {
const type = parseIntOr(data.type, null);
if (type == null) throw new TypeError("missing item type.");
- switch (type as VisualConsoleItemType) {
- case VisualConsoleItemType.STATIC_GRAPH:
+ switch (type as ItemType) {
+ case ItemType.STATIC_GRAPH:
return new StaticGraph(staticGraphPropsDecoder(data));
- case VisualConsoleItemType.MODULE_GRAPH:
+ case ItemType.MODULE_GRAPH:
throw new TypeError("item not found");
- case VisualConsoleItemType.SIMPLE_VALUE:
+ case ItemType.SIMPLE_VALUE:
throw new TypeError("item not found");
- case VisualConsoleItemType.PERCENTILE_BAR:
+ case ItemType.PERCENTILE_BAR:
throw new TypeError("item not found");
- case VisualConsoleItemType.LABEL:
+ case ItemType.LABEL:
throw new TypeError("item not found");
- case VisualConsoleItemType.ICON:
+ case ItemType.ICON:
return new Icon(iconPropsDecoder(data));
- case VisualConsoleItemType.SIMPLE_VALUE_MAX:
+ case ItemType.SIMPLE_VALUE_MAX:
throw new TypeError("item not found");
- case VisualConsoleItemType.SIMPLE_VALUE_MIN:
+ case ItemType.SIMPLE_VALUE_MIN:
throw new TypeError("item not found");
- case VisualConsoleItemType.SIMPLE_VALUE_AVG:
+ case ItemType.SIMPLE_VALUE_AVG:
throw new TypeError("item not found");
- case VisualConsoleItemType.PERCENTILE_BUBBLE:
+ case ItemType.PERCENTILE_BUBBLE:
throw new TypeError("item not found");
- case VisualConsoleItemType.SERVICE:
+ case ItemType.SERVICE:
throw new TypeError("item not found");
- case VisualConsoleItemType.GROUP_ITEM:
+ case ItemType.GROUP_ITEM:
return new Group(groupPropsDecoder(data));
- case VisualConsoleItemType.BOX_ITEM:
+ case ItemType.BOX_ITEM:
+ return new Box(boxPropsDecoder(data));
+ case ItemType.LINE_ITEM:
throw new TypeError("item not found");
- case VisualConsoleItemType.LINE_ITEM:
+ case ItemType.AUTO_SLA_GRAPH:
throw new TypeError("item not found");
- case VisualConsoleItemType.AUTO_SLA_GRAPH:
+ case ItemType.CIRCULAR_PROGRESS_BAR:
throw new TypeError("item not found");
- case VisualConsoleItemType.CIRCULAR_PROGRESS_BAR:
+ case ItemType.CIRCULAR_INTERIOR_PROGRESS_BAR:
throw new TypeError("item not found");
- case VisualConsoleItemType.CIRCULAR_INTERIOR_PROGRESS_BAR:
+ case ItemType.DONUT_GRAPH:
throw new TypeError("item not found");
- case VisualConsoleItemType.DONUT_GRAPH:
+ case ItemType.BARS_GRAPH:
throw new TypeError("item not found");
- case VisualConsoleItemType.BARS_GRAPH:
- throw new TypeError("item not found");
- case VisualConsoleItemType.CLOCK:
+ case ItemType.CLOCK:
return new Clock(clockPropsDecoder(data));
- case VisualConsoleItemType.COLOR_CLOUD:
+ case ItemType.COLOR_CLOUD:
return new ColorCloud(colorCloudPropsDecoder(data));
default:
throw new TypeError("item not found");
@@ -129,7 +126,7 @@ export default class VisualConsole {
// Properties.
private _props: VisualConsoleProps;
// Visual Console Item instances.
- private elements: VisualConsoleItem[] = [];
+ private elements: Item[] = [];
public constructor(
container: HTMLElement,
diff --git a/visual_console/src/items/Box.ts b/visual_console/src/items/Box.ts
new file mode 100644
index 0000000000..3dca242a88
--- /dev/null
+++ b/visual_console/src/items/Box.ts
@@ -0,0 +1,65 @@
+import { UnknownObject } from "../types";
+import { parseIntOr, notEmptyStringOr } from "../lib";
+import Item, { ItemType, ItemProps, itemBasePropsDecoder } from "../Item";
+
+interface BoxProps extends ItemProps {
+ // Overrided properties.
+ readonly type: ItemType.BOX_ITEM;
+ label: null;
+ isLinkEnabled: false;
+ parentId: null;
+ aclGroupId: null;
+ // Custom properties.
+ borderWidth: number;
+ borderColor: string | null;
+ fillColor: string | null;
+}
+
+/**
+ * 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 item props.
+ * @throws Will throw a TypeError if some property
+ * is missing from the raw object or have an invalid type.
+ */
+export function boxPropsDecoder(data: UnknownObject): BoxProps | never {
+ return {
+ ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.
+ type: ItemType.BOX_ITEM,
+ label: null,
+ isLinkEnabled: false,
+ parentId: null,
+ aclGroupId: null,
+ // Custom properties.
+ borderWidth: parseIntOr(data.borderWidth, 0),
+ borderColor: notEmptyStringOr(data.borderColor, null),
+ fillColor: notEmptyStringOr(data.fillColor, null)
+ };
+}
+
+export default class Box extends Item {
+ public createDomElement(): HTMLElement {
+ const box: HTMLDivElement = document.createElement("div");
+ box.className = "box";
+ // To prevent this item to expand beyond its parent.
+ box.style.boxSizing = "border-box";
+
+ if (this.props.fillColor) {
+ box.style.backgroundColor = this.props.fillColor;
+ }
+
+ // Border.
+ if (this.props.borderWidth > 0) {
+ box.style.borderStyle = "solid";
+ box.style.borderWidth = `${this.props.borderWidth}px`;
+
+ if (this.props.borderColor) {
+ box.style.borderColor = this.props.borderColor;
+ }
+ }
+
+ return box;
+ }
+}