Integration/human readable time (#405)

* refactor: remove unused code

* feat: add human readable values to message parsing

---------

Co-authored-by: Fabian Posenau <fabian@fphome.de>
Co-authored-by: cv <34649812+cpvalente@users.noreply.github.com>
This commit is contained in:
Fabian Posenau
2023-06-05 20:48:53 +02:00
committed by GitHub
parent bfb483508d
commit 7cfe7c0d78
19 changed files with 302 additions and 271 deletions
@@ -1,34 +1,65 @@
// any value inside double curly braces {{val}}
import { formatDisplay } from 'ontime-utils';
const placeholderRegex = /{{(.*?)}}/g;
/**
* Parses a templated string
*/
export function parseTemplate(template: string, state: object): string {
let parsedTemplate = template;
let match;
while ((match = placeholderRegex.exec(template)) !== null) {
const variableName = match[1];
if (Object.hasOwn(state, variableName)) {
parsedTemplate = parsedTemplate.replace(match[0], state[variableName]);
function formatDisplayFromString(value: string, hideZero = false): string {
let valueInNumber = null;
if (value !== 'null') {
const parsedValue = Number(value);
if (!Number.isNaN(parsedValue)) {
valueInNumber = parsedValue;
}
}
return parsedTemplate;
return formatDisplay(valueInNumber, hideZero);
}
type AliasesDefinition = Record<string, { key: string; cb: (value: unknown) => string }>;
const quickAliases: AliasesDefinition = {
clock: { key: 'timer.clock', cb: (value: string) => formatDisplayFromString(value) },
duration: { key: 'timer.duration', cb: (value: string) => formatDisplayFromString(value, true) },
expectedEnd: {
key: 'timer.expectedFinish',
cb: (value: string) => formatDisplayFromString(value),
},
runningTimer: {
key: 'timer.current',
cb: (value: string) => formatDisplayFromString(value, true),
},
elapsedTime: {
key: 'timer.elapsed',
cb: (value: string) => formatDisplayFromString(value, true),
},
startedAt: { key: 'timer.startedAt', cb: (value: string) => formatDisplayFromString(value) },
};
/**
* Parses a templated string to values in a nested object
*/
export function parseTemplateNested(template: string, state: object): string {
export function parseTemplateNested(template: string, state: object, humanReadable = quickAliases): string {
let parsedTemplate = template;
let match;
while ((match = placeholderRegex.exec(template)) !== null) {
const matches = Array.from(parsedTemplate.matchAll(placeholderRegex));
for (const match of matches) {
const variableName = match[1];
const variableParts = variableName.split('.');
// iterate through variable parts, and look for the property in the state object
const value = variableParts.reduce((obj, key) => obj && obj[key], state);
if (value !== undefined) {
let value = undefined;
if (variableParts[0] === 'human') {
const lookupKey = variableParts[1];
if (lookupKey in humanReadable) {
const newTemplate = `{{${humanReadable[lookupKey].key}}}`;
const parsed = parseTemplateNested(newTemplate, state, humanReadable);
value = humanReadable[lookupKey].cb(parsed);
} else {
value = undefined;
}
} else {
// iterate through variable parts, and look for the property in the state object
value = variableParts.reduce((obj, key) => obj && obj[key], state);
}
if (typeof value !== 'undefined') {
parsedTemplate = parsedTemplate.replace(match[0], value);
}
}