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; + } +}