Visual Console Refactor: added the missing macros to the label

Former-commit-id: 2e52a35c0f571d6162cbd3fb1188c3f47b77a8a5
This commit is contained in:
Alejandro Gallardo Escobar 2019-04-24 15:58:33 +02:00
parent 9112b1b685
commit 3c2e65a8a5
11 changed files with 125 additions and 30 deletions

View File

@ -73,6 +73,10 @@ final class SimpleValue extends Item
$return['period'] = static::extractPeriod($data);
}
// Clear the size, as this element always have a dynamic size.
$return['width'] = 0;
$return['height'] = 0;
return $return;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,10 +1,13 @@
import { Position, Size, UnknownObject } from "./types";
import { Position, Size, UnknownObject, WithModuleProps } from "./types";
import {
sizePropsDecoder,
positionPropsDecoder,
parseIntOr,
parseBoolean,
notEmptyStringOr
notEmptyStringOr,
replaceMacros,
humanDate,
humanTime
} from "./lib";
import TypedEvent, { Listener, Disposable } from "./TypedEvent";
@ -196,7 +199,8 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
const element = document.createElement("div");
element.className = "visual-console-item-label";
// Add the label if it exists.
if (this.props.label && this.props.label.length) {
const label = this.getLabelWithMacrosReplaced();
if (label.length > 0) {
// Ugly table we need to use to replicate the legacy style.
const table = document.createElement("table");
const row = document.createElement("tr");
@ -204,7 +208,7 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
const emptyRow2 = document.createElement("tr");
const cell = document.createElement("td");
cell.innerHTML = this.props.label;
cell.innerHTML = label;
row.append(cell);
table.append(emptyRow1, row, emptyRow2);
@ -215,6 +219,48 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
return element;
}
/**
* Return the label stored into the props with some macros replaced.
*/
protected getLabelWithMacrosReplaced(): string {
// We assert that the props may have some needed properties.
const props = this.props as Partial<WithModuleProps>;
return replaceMacros(
[
{
macro: "_date_",
value: humanDate(new Date())
},
{
macro: "_time_",
value: humanTime(new Date())
},
{
macro: "_agent_",
value: props.agentAlias != null ? props.agentAlias : ""
},
{
macro: "_agentdescription_",
value: props.agentDescription != null ? props.agentDescription : ""
},
{
macro: "_address_",
value: props.agentAddress != null ? props.agentAddress : ""
},
{
macro: "_module_",
value: props.moduleName != null ? props.moduleName : ""
},
{
macro: "_moduledescription_",
value: props.moduleDescription != null ? props.moduleDescription : ""
}
],
this.props.label || ""
);
}
/**
* To update the content element.
* @return Item.
@ -280,8 +326,14 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
this.resizeElement(this.props.width, this.props.height);
}
// Change label.
if (!prevProps || prevProps.label !== this.props.label) {
this.labelElementRef.innerHTML = this.createLabelDomElement().innerHTML;
const oldLabelHtml = this.labelElementRef.innerHTML;
const newLabelHtml = this.createLabelDomElement().innerHTML;
if (oldLabelHtml !== newLabelHtml) {
this.labelElementRef.innerHTML = newLabelHtml;
}
// Change label position.
if (!prevProps || prevProps.labelPosition !== this.props.labelPosition) {
this.changeLabelPosition(this.props.labelPosition);
}
// Change link.
if (
@ -299,10 +351,6 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
// Changed the reference to the main element. It's ugly, but needed.
this.elementRef = container;
}
// Change label position.
if (!prevProps || prevProps.labelPosition !== this.props.labelPosition) {
this.changeLabelPosition(this.props.labelPosition);
}
}
/**

View File

@ -28,7 +28,7 @@ export default class Label extends Item<LabelProps> {
protected createDomElement(): HTMLElement {
const element = document.createElement("div");
element.className = "label";
element.innerHTML = this.props.label || "";
element.innerHTML = this.getLabelWithMacrosReplaced();
return element;
}

View File

@ -3,7 +3,12 @@ import {
UnknownObject,
WithModuleProps
} from "../types";
import { linkedVCPropsDecoder, parseIntOr, modulePropsDecoder } from "../lib";
import {
linkedVCPropsDecoder,
parseIntOr,
modulePropsDecoder,
replaceMacros
} from "../lib";
import Item, { ItemType, ItemProps, itemBasePropsDecoder } from "../Item";
export type SimpleValueProps = {
@ -99,8 +104,9 @@ export default class SimpleValue extends Item<SimpleValueProps> {
} else {
// Add the value to the label and show it.
let text = this.props.value;
if (this.props.label) {
text = this.props.label.replace(/\(?_VALUE_\)?/i, text);
let label = this.getLabelWithMacrosReplaced();
if (label.length > 0) {
text = replaceMacros([{ macro: /\(?_VALUE_\)?/i, value: text }], label);
}
element.innerHTML = text;

View File

@ -6,7 +6,8 @@ import {
prefixedCssRules,
decodeBase64,
humanDate,
humanTime
humanTime,
replaceMacros
} from "./lib";
describe("function parseIntOr", () => {
@ -99,3 +100,21 @@ describe("humanTime function", () => {
expect(digitalTime).toBe(expected);
});
});
describe("replaceMacros function", () => {
const macros = [
{ macro: "_foo_", value: "foo" },
{ macro: "_bar_", value: "bar" },
{ macro: "_baz_", value: "baz" }
];
it("should not replace anything if it doesn't find any macro", () => {
const text = "Lorem Ipsum";
expect(replaceMacros(macros, text)).toBe(text);
});
it("should replace the macros", () => {
const text = "Lorem _foo_ Ipsum _baz_";
expect(replaceMacros(macros, text)).toBe("Lorem foo Ipsum baz");
});
});

View File

@ -149,17 +149,17 @@ export function sizePropsDecoder(data: UnknownObject): Size | never {
* @return An object representing the agent properties.
*/
export function agentPropsDecoder(data: UnknownObject): WithAgentProps {
// Object destructuring: http://es6-features.org/#ObjectMatchingShorthandNotation
const { metaconsoleId, agentId: id, agentName: name } = data;
const agentProps: WithAgentProps = {
agentId: parseIntOr(id, null),
agentName: typeof name === "string" && name.length > 0 ? name : null
agentId: parseIntOr(data.agent, null),
agentName: notEmptyStringOr(data.agentName, null),
agentAlias: notEmptyStringOr(data.agentAlias, null),
agentDescription: notEmptyStringOr(data.agentDescription, null),
agentAddress: notEmptyStringOr(data.agentAddress, null)
};
return metaconsoleId != null
return data.metaconsoleId != null
? {
metaconsoleId,
metaconsoleId: data.metaconsoleId,
...agentProps // Object spread: http://es6-features.org/#SpreadOperator
}
: agentProps;
@ -171,12 +171,10 @@ export function agentPropsDecoder(data: UnknownObject): WithAgentProps {
* @return An object representing the module and agent properties.
*/
export function modulePropsDecoder(data: UnknownObject): WithModuleProps {
// Object destructuring: http://es6-features.org/#ObjectMatchingShorthandNotation
const { moduleId: id, moduleName: name } = data;
return {
moduleId: parseIntOr(id, null),
moduleName: typeof name === "string" && name.length > 0 ? name : null,
moduleId: parseIntOr(data.moduleId, null),
moduleName: notEmptyStringOr(data.moduleName, null),
moduleDescription: notEmptyStringOr(data.moduleDescription, null),
...agentPropsDecoder(data) // Object spread: http://es6-features.org/#SpreadOperator
};
}
@ -319,3 +317,19 @@ export function humanTime(date: Date): string {
return `${hours}:${minutes}:${seconds}`;
}
interface Macro {
macro: string | RegExp;
value: string;
}
/**
* Replace the macros of a text.
* @param macros List of macros and their replacements.
* @param text Text in which we need to replace the macros.
*/
export function replaceMacros(macros: Macro[], text: string): string {
return macros.reduce(
(acc, { macro, value }) => acc.replace(macro, value),
text
);
}

View File

@ -16,11 +16,15 @@ export interface WithAgentProps {
metaconsoleId?: number | null;
agentId: number | null;
agentName: string | null;
agentAlias: string | null;
agentDescription: string | null;
agentAddress: string | null;
}
export interface WithModuleProps extends WithAgentProps {
moduleId: number | null;
moduleName: string | null;
moduleDescription: string | null;
}
export type LinkedVisualConsolePropsStatus =