Merge branch 'visual-console-refactor' of https://brutus.artica.lan:8081/artica/pandorafms into visual-console-refactor
Former-commit-id: 50ffdbe852fe3dc88ba1705ce769f8ec70bc7506
This commit is contained in:
commit
56fef21bc6
|
@ -18,10 +18,10 @@
|
|||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
|
@ -86,4 +86,4 @@
|
|||
animation: rotate-second 60s infinite linear;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=vc.main.ba23d758.css.map*/
|
||||
/*# sourceMappingURL=vc.main.402dd2b3.css.map*/
|
|
@ -1 +1 @@
|
|||
{"version":3,"sources":["webpack:///main.css","webpack:///styles.css"],"names":[],"mappings":"AAAA;EACE,gBAAgB;EAChB,kBAAkB;EAClB,4BAA4B;EAC5B,wBAAwB;AAC1B;;AAEA;EACE,kBAAkB;EAClB,oBAAa;EAAb,oBAAa;EAAb,aAAa;EACb,2BAAuB;EAAvB,8BAAuB;MAAvB,2BAAuB;UAAvB,uBAAuB;EACvB,qBAAqB;EACrB,yBAAmB;MAAnB,sBAAmB;UAAnB,mBAAmB;EACnB,yBAAiB;KAAjB,sBAAiB;MAAjB,qBAAiB;UAAjB,iBAAiB;AACnB;;ACdA;EACE,wBAAwB;EACxB,kCAA2B;AAC7B;;AAEA,kBAAkB;;AAElB;EACE,oBAAa;EAAb,oBAAa;EAAb,aAAa;EACb,4BAAsB;EAAtB,6BAAsB;MAAtB,0BAAsB;UAAtB,sBAAsB;EACtB,wBAAuB;MAAvB,qBAAuB;UAAvB,uBAAuB;EACvB,qBAAqB;EACrB,0BAAqB;MAArB,qBAAqB;EACrB,yBAAmB;MAAnB,sBAAmB;UAAnB,mBAAmB;AACrB;;AAEA;EACE,6DAA6D;EAC7D,eAAe;;EAEf,0BAA0B;EAC1B,mCAAmC;EACnC,kCAAkC;EAClC,kCAAkC;EAClC,wCAAwC;AAC1C;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,eAAe;AACjB;;AAEA,iBAAiB;;AAEjB;EACE,qDAA6C;UAA7C,6CAA6C;AAC/C;;AAEA;EACE,sDAA8C;UAA9C,8CAA8C;AAChD;;AAEA;EACE,oDAA4C;UAA5C,4CAA4C;AAC9C","file":"vc.main.ba23d758.css","sourcesContent":["#visual-console-container {\n margin: 0px auto;\n position: relative;\n background-repeat: no-repeat;\n background-size: contain;\n}\n\n.visual-console-item {\n position: absolute;\n display: flex;\n flex-direction: initial;\n justify-items: center;\n align-items: center;\n user-select: none;\n}\n","@font-face {\n font-family: Alarm Clock;\n src: url(./alarm-clock.ttf);\n}\n\n/* Digital clock */\n\n.visual-console-item .digital-clock {\n display: flex;\n flex-direction: column;\n justify-content: center;\n justify-items: center;\n align-content: center;\n align-items: center;\n}\n\n.visual-console-item .digital-clock > span {\n font-family: \"Alarm Clock\", \"Courier New\", Courier, monospace;\n font-size: 50px;\n\n /* To improve legibility */\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-rendering: optimizeLegibility;\n text-shadow: rgba(0, 0, 0, 0.01) 0 0 1px;\n}\n\n.visual-console-item .digital-clock > span.date {\n font-size: 25px;\n}\n\n.visual-console-item .digital-clock > span.timezone {\n font-size: 25px;\n}\n\n/* Analog clock */\n\n.visual-console-item .analogic-clock .hour-hand {\n animation: rotate-hour 43200s infinite linear;\n}\n\n.visual-console-item .analogic-clock .minute-hand {\n animation: rotate-minute 3600s infinite linear;\n}\n\n.visual-console-item .analogic-clock .second-hand {\n animation: rotate-second 60s infinite linear;\n}\n"],"sourceRoot":""}
|
||||
{"version":3,"sources":["webpack:///main.css","webpack:///styles.css"],"names":[],"mappings":"AAAA;EACE,gBAAgB;EAChB,kBAAkB;EAClB,4BAA4B;EAC5B,wBAAwB;AAC1B;;AAEA;EACE,kBAAkB;EAClB,oBAAa;EAAb,oBAAa;EAAb,aAAa;EACb,2BAAuB;EAAvB,8BAAuB;MAAvB,2BAAuB;UAAvB,uBAAuB;EACvB,qBAAqB;EACrB,yBAAmB;MAAnB,sBAAmB;UAAnB,mBAAmB;EACnB,yBAAiB;KAAjB,sBAAiB;MAAjB,qBAAiB;UAAjB,iBAAiB;AACnB;;ACdA;EACE,wBAAwB;EACxB,kCAA2B;AAC7B;;AAEA,kBAAkB;;AAElB;EACE,oBAAa;EAAb,oBAAa;EAAb,aAAa;EACb,4BAAsB;EAAtB,6BAAsB;MAAtB,0BAAsB;UAAtB,sBAAsB;EACtB,wBAAuB;MAAvB,qBAAuB;UAAvB,uBAAuB;EACvB,qBAAqB;EACrB,0BAAqB;MAArB,qBAAqB;EACrB,yBAAmB;MAAnB,sBAAmB;UAAnB,mBAAmB;AACrB;;AAEA;EACE,6DAA6D;EAC7D,eAAe;;EAEf,0BAA0B;EAC1B,mCAAmC;EACnC,kCAAkC;EAClC,kCAAkC;EAClC,wCAAwC;AAC1C;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,eAAe;AACjB;;AAEA,iBAAiB;;AAEjB;EACE,qDAA6C;UAA7C,6CAA6C;AAC/C;;AAEA;EACE,sDAA8C;UAA9C,8CAA8C;AAChD;;AAEA;EACE,oDAA4C;UAA5C,4CAA4C;AAC9C","file":"vc.main.402dd2b3.css","sourcesContent":["#visual-console-container {\n margin: 0px auto;\n position: relative;\n background-repeat: no-repeat;\n background-size: contain;\n}\n\n.visual-console-item {\n position: absolute;\n display: flex;\n flex-direction: initial;\n justify-items: center;\n align-items: center;\n user-select: text;\n}\n","@font-face {\n font-family: Alarm Clock;\n src: url(./alarm-clock.ttf);\n}\n\n/* Digital clock */\n\n.visual-console-item .digital-clock {\n display: flex;\n flex-direction: column;\n justify-content: center;\n justify-items: center;\n align-content: center;\n align-items: center;\n}\n\n.visual-console-item .digital-clock > span {\n font-family: \"Alarm Clock\", \"Courier New\", Courier, monospace;\n font-size: 50px;\n\n /* To improve legibility */\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-rendering: optimizeLegibility;\n text-shadow: rgba(0, 0, 0, 0.01) 0 0 1px;\n}\n\n.visual-console-item .digital-clock > span.date {\n font-size: 25px;\n}\n\n.visual-console-item .digital-clock > span.timezone {\n font-size: 25px;\n}\n\n/* Analog clock */\n\n.visual-console-item .analogic-clock .hour-hand {\n animation: rotate-hour 43200s infinite linear;\n}\n\n.visual-console-item .analogic-clock .minute-hand {\n animation: rotate-minute 3600s infinite linear;\n}\n\n.visual-console-item .analogic-clock .second-hand {\n animation: rotate-second 60s infinite linear;\n}\n"],"sourceRoot":""}
|
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
|
@ -197,7 +197,34 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
|
|||
element.className = "visual-console-item-label";
|
||||
// Add the label if it exists.
|
||||
if (this.props.label && this.props.label.length) {
|
||||
element.innerHTML = this.props.label;
|
||||
// Ugly table we need to use to replicate the legacy style.
|
||||
const table = document.createElement("table");
|
||||
const row = document.createElement("tr");
|
||||
const emptyRow1 = document.createElement("tr");
|
||||
const emptyRow2 = document.createElement("tr");
|
||||
const cell = document.createElement("td");
|
||||
|
||||
cell.innerHTML = this.props.label;
|
||||
row.append(cell);
|
||||
table.append(emptyRow1, row, emptyRow2);
|
||||
|
||||
switch (this.props.labelPosition) {
|
||||
case "up":
|
||||
case "down":
|
||||
if (this.props.width > 0) {
|
||||
table.style.width = `${this.props.width}px`;
|
||||
}
|
||||
break;
|
||||
case "left":
|
||||
case "right":
|
||||
if (this.props.height > 0) {
|
||||
table.style.height = `${this.props.height}px`;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// element.innerHTML = this.props.label;
|
||||
element.append(table);
|
||||
}
|
||||
|
||||
return element;
|
||||
|
|
|
@ -4,10 +4,11 @@ import { LinkedVisualConsoleProps, UnknownObject, Size } from "../../types";
|
|||
import {
|
||||
linkedVCPropsDecoder,
|
||||
parseIntOr,
|
||||
padLeft,
|
||||
parseBoolean,
|
||||
prefixedCssRules,
|
||||
notEmptyStringOr
|
||||
notEmptyStringOr,
|
||||
humanDate,
|
||||
humanTime
|
||||
} from "../../lib";
|
||||
import Item, { ItemProps, itemBasePropsDecoder, ItemType } from "../../Item";
|
||||
|
||||
|
@ -388,7 +389,7 @@ export default class Clock extends Item<ClockProps> {
|
|||
pin.setAttribute("fill", colors.handDark);
|
||||
|
||||
// Get the hand angles.
|
||||
const date = this.getDate();
|
||||
const date = this.getOriginDate();
|
||||
const seconds = date.getSeconds();
|
||||
const minutes = date.getMinutes();
|
||||
const hours = date.getHours();
|
||||
|
@ -492,11 +493,14 @@ export default class Clock extends Item<ClockProps> {
|
|||
(width / 100) * 10
|
||||
);
|
||||
|
||||
// Date calculated using the original timezone.
|
||||
const date = this.getOriginDate();
|
||||
|
||||
// Date.
|
||||
if (this.props.clockFormat === "datetime") {
|
||||
const dateElem: HTMLSpanElement = document.createElement("span");
|
||||
dateElem.className = "date";
|
||||
dateElem.textContent = this.getDigitalDate();
|
||||
dateElem.textContent = humanDate(date, "default");
|
||||
dateElem.style.fontSize = `${dateFontSize}px`;
|
||||
if (this.props.color) dateElem.style.color = this.props.color;
|
||||
element.append(dateElem);
|
||||
|
@ -505,7 +509,7 @@ export default class Clock extends Item<ClockProps> {
|
|||
// Time.
|
||||
const timeElem: HTMLSpanElement = document.createElement("span");
|
||||
timeElem.className = "time";
|
||||
timeElem.textContent = this.getDigitalTime();
|
||||
timeElem.textContent = humanTime(date);
|
||||
timeElem.style.fontSize = `${timeFontSize}px`;
|
||||
if (this.props.color) timeElem.style.color = this.props.color;
|
||||
element.append(timeElem);
|
||||
|
@ -528,8 +532,8 @@ export default class Clock extends Item<ClockProps> {
|
|||
* Generate the current date using the timezone offset stored into the properties.
|
||||
* @return The current date.
|
||||
*/
|
||||
private getDate(): Date {
|
||||
const d = new Date();
|
||||
private getOriginDate(initialDate: Date | null = null): Date {
|
||||
const d = initialDate ? initialDate : new Date();
|
||||
const targetTZOffset = this.props.clockTimezoneOffset * 1000; // In ms.
|
||||
const localTZOffset = d.getTimezoneOffset() * 60 * 1000; // In ms.
|
||||
const utimestamp = d.getTime() + targetTZOffset + localTZOffset;
|
||||
|
@ -537,37 +541,6 @@ export default class Clock extends Item<ClockProps> {
|
|||
return new Date(utimestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a date representation with the format 'd/m/Y'.
|
||||
* @example 24/02/2020.
|
||||
* @return Date representation.
|
||||
*/
|
||||
public getDigitalDate(initialDate: Date | null = null): string {
|
||||
const date = initialDate || this.getDate();
|
||||
// Use getDate, getDay returns the week day.
|
||||
const day = padLeft(date.getDate(), 2, 0);
|
||||
// The getMonth function returns the month starting by 0.
|
||||
const month = padLeft(date.getMonth() + 1, 2, 0);
|
||||
const year = padLeft(date.getFullYear(), 4, 0);
|
||||
|
||||
// Format: 'd/m/Y'.
|
||||
return `${day}/${month}/${year}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a time representation with the format 'hh:mm:ss'.
|
||||
* @example 01:34:09.
|
||||
* @return Time representation.
|
||||
*/
|
||||
public getDigitalTime(initialDate: Date | null = null): string {
|
||||
const date = initialDate || this.getDate();
|
||||
const hours = padLeft(date.getHours(), 2, 0);
|
||||
const minutes = padLeft(date.getMinutes(), 2, 0);
|
||||
const seconds = padLeft(date.getSeconds(), 2, 0);
|
||||
|
||||
return `${hours}:${minutes}:${seconds}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a human readable city name from the timezone text.
|
||||
* @param timezone Timezone text.
|
||||
|
|
|
@ -55,24 +55,6 @@ describe("Clock item", () => {
|
|||
).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
describe("getDate function", () => {
|
||||
it("should return the date with padded 0's", () => {
|
||||
const expected = "01/02/0123";
|
||||
const date = new Date(`02/01/0123 12:00:00`);
|
||||
const digitalDate = clockInstance.getDigitalDate(date);
|
||||
expect(digitalDate).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getTime function", () => {
|
||||
it("should return the time with padded 0's when hours/minutes/seconds are less than 10", () => {
|
||||
const expected = "01:02:03";
|
||||
const date = new Date(`01/01/1970 ${expected}`);
|
||||
const digitalTime = clockInstance.getDigitalTime(date);
|
||||
expect(digitalTime).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getHumanTimezone function", () => {
|
||||
it("should return a better timezone", () => {
|
||||
expect(clockInstance.getHumanTimezone("America/New_York")).toBe(
|
||||
|
|
|
@ -2,9 +2,11 @@ import {
|
|||
parseIntOr,
|
||||
stringIsEmpty,
|
||||
notEmptyStringOr,
|
||||
padLeft,
|
||||
leftPad,
|
||||
prefixedCssRules,
|
||||
decodeBase64
|
||||
decodeBase64,
|
||||
humanDate,
|
||||
humanTime
|
||||
} from "./lib";
|
||||
|
||||
describe("function parseIntOr", () => {
|
||||
|
@ -40,18 +42,18 @@ describe("function notEmptyStringOr", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("function padLeft", () => {
|
||||
describe("function leftPad", () => {
|
||||
it("should pad properly", () => {
|
||||
expect(padLeft(1, 2, 0)).toBe("01");
|
||||
expect(padLeft(1, 4, 0)).toBe("0001");
|
||||
expect(padLeft(1, 4, "0")).toBe("0001");
|
||||
expect(padLeft("1", 4, "0")).toBe("0001");
|
||||
expect(padLeft(10, 4, 0)).toBe("0010");
|
||||
expect(padLeft("bar", 6, "foo")).toBe("foobar");
|
||||
expect(padLeft("bar", 11, "foo")).toBe("foofoofobar");
|
||||
expect(padLeft("bar", 4, "foo")).toBe("fbar");
|
||||
expect(padLeft("bar", 2, "foo")).toBe("ar");
|
||||
expect(padLeft("bar", 3, "foo")).toBe("bar");
|
||||
expect(leftPad(1, 2, 0)).toBe("01");
|
||||
expect(leftPad(1, 4, 0)).toBe("0001");
|
||||
expect(leftPad(1, 4, "0")).toBe("0001");
|
||||
expect(leftPad("1", 4, "0")).toBe("0001");
|
||||
expect(leftPad(10, 4, 0)).toBe("0010");
|
||||
expect(leftPad("bar", 6, "foo")).toBe("foobar");
|
||||
expect(leftPad("bar", 11, "foo")).toBe("foofoofobar");
|
||||
expect(leftPad("bar", 4, "foo")).toBe("fbar");
|
||||
expect(leftPad("bar", 2, "foo")).toBe("ar");
|
||||
expect(leftPad("bar", 3, "foo")).toBe("bar");
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -79,3 +81,21 @@ describe("function decodeBase64", () => {
|
|||
).toEqual("<div>Box <p>Paragraph</p><hr /></div>");
|
||||
});
|
||||
});
|
||||
|
||||
describe("humanDate function", () => {
|
||||
it("should return the date with padded 0's", () => {
|
||||
const expected = "01/02/0123";
|
||||
const date = new Date(`02/01/0123 12:00:00`);
|
||||
const digitalDate = humanDate(date);
|
||||
expect(digitalDate).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe("humanTime function", () => {
|
||||
it("should return the time with padded 0's when hours/minutes/seconds are less than 10", () => {
|
||||
const expected = "01:02:03";
|
||||
const date = new Date(`01/01/1970 ${expected}`);
|
||||
const digitalTime = humanTime(date);
|
||||
expect(digitalTime).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -82,7 +82,7 @@ export function parseBoolean(value: any): boolean {
|
|||
* @param pad Text to add.
|
||||
* @return Padded text.
|
||||
*/
|
||||
export function padLeft(
|
||||
export function leftPad(
|
||||
value: string | number,
|
||||
length: number,
|
||||
pad: string | number = " "
|
||||
|
@ -277,3 +277,45 @@ export function prefixedCssRules(
|
|||
export function decodeBase64(input: string): string {
|
||||
return decodeURIComponent(escape(window.atob(input)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a date representation with the format 'd/m/Y'.
|
||||
* @param initialDate Date to be used instead of a generated one.
|
||||
* @param locale Locale to use if localization is required and available.
|
||||
* @example 24/02/2020.
|
||||
* @return Date representation.
|
||||
*/
|
||||
export function humanDate(date: Date, locale: string | null = null): string {
|
||||
if (locale && Intl && Intl.DateTimeFormat) {
|
||||
// Format using the user locale.
|
||||
const options: Intl.DateTimeFormatOptions = {
|
||||
day: "2-digit",
|
||||
month: "2-digit",
|
||||
year: "numeric"
|
||||
};
|
||||
return Intl.DateTimeFormat(locale, options).format(date);
|
||||
} else {
|
||||
// Use getDate, getDay returns the week day.
|
||||
const day = leftPad(date.getDate(), 2, 0);
|
||||
// The getMonth function returns the month starting by 0.
|
||||
const month = leftPad(date.getMonth() + 1, 2, 0);
|
||||
const year = leftPad(date.getFullYear(), 4, 0);
|
||||
|
||||
// Format: 'd/m/Y'.
|
||||
return `${day}/${month}/${year}`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a time representation with the format 'hh:mm:ss'.
|
||||
* @param initialDate Date to be used instead of a generated one.
|
||||
* @example 01:34:09.
|
||||
* @return Time representation.
|
||||
*/
|
||||
export function humanTime(date: Date): string {
|
||||
const hours = leftPad(date.getHours(), 2, 0);
|
||||
const minutes = leftPad(date.getMinutes(), 2, 0);
|
||||
const seconds = leftPad(date.getSeconds(), 2, 0);
|
||||
|
||||
return `${hours}:${minutes}:${seconds}`;
|
||||
}
|
||||
|
|
|
@ -11,5 +11,5 @@
|
|||
flex-direction: initial;
|
||||
justify-items: center;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
user-select: text;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue