Merge branch 'new-vc-line-element' of https://brutus.artica.lan:8081/artica/pandorafms into new-vc-line-element
This commit is contained in:
commit
996e7df1db
|
@ -110,10 +110,13 @@ if ($getVisualConsole === true) {
|
|||
return;
|
||||
} else if ($updateVisualConsoleItem === true) {
|
||||
$data = get_parameter('data');
|
||||
$data['id'] = $itemId;
|
||||
$result = $item->save($data);
|
||||
if ($data) {
|
||||
$data['id'] = $itemId;
|
||||
$result = $item->save($data);
|
||||
|
||||
echo $item;
|
||||
}
|
||||
|
||||
echo $item;
|
||||
return;
|
||||
}
|
||||
} else if ($removeVisualConsoleItem === true) {
|
||||
|
|
|
@ -1816,7 +1816,7 @@ class Item extends CachedModel
|
|||
// Invalidate the item's cache.
|
||||
if ($result !== false && $result > 0) {
|
||||
// TODO: Invalidate the cache with the function clearCachedData.
|
||||
db_process_sql_delete(
|
||||
\db_process_sql_delete(
|
||||
'tvisual_console_elements_cache',
|
||||
[
|
||||
'vc_item_id' => (int) $save['id'],
|
||||
|
|
|
@ -28,6 +28,50 @@ final class ColorCloud extends Item
|
|||
protected static $useLinkedModule = true;
|
||||
|
||||
|
||||
/**
|
||||
* Return a valid representation of a record in database.
|
||||
*
|
||||
* @param array $data Input data.
|
||||
*
|
||||
* @return array Data structure representing a record in database.
|
||||
*
|
||||
* @overrides Item->encode.
|
||||
*/
|
||||
protected function encode(array $data): array
|
||||
{
|
||||
$return = parent::encode($data);
|
||||
|
||||
$defaultColor = null;
|
||||
if (isset($data['defaultColor']) === true) {
|
||||
$defaultColor = static::extractDefaultColor($data);
|
||||
}
|
||||
|
||||
$colorRanges = null;
|
||||
if (isset($data['colorRanges']) === true) {
|
||||
$colorRanges = static::extractColorRanges($data);
|
||||
}
|
||||
|
||||
if (empty($data['id']) === true) {
|
||||
$return['label'] = json_encode(
|
||||
[
|
||||
'default_color' => $defaultColor,
|
||||
'color_ranges' => $colorRanges,
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$prevData = $this->toArray();
|
||||
$return['label'] = json_encode(
|
||||
[
|
||||
'default_color' => ($defaultColor !== null) ? $defaultColor : $prevData['defaultColor'],
|
||||
'color_ranges' => ($colorRanges !== null) ? $colorRanges : $prevData['colorRanges'],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a valid representation of the model.
|
||||
*
|
||||
|
|
|
@ -1197,7 +1197,9 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
|
|||
}
|
||||
|
||||
box.className = "visual-console-item";
|
||||
box.style.zIndex = this.props.isOnTop ? "2" : "1";
|
||||
if (this.props.isOnTop) {
|
||||
box.classList.add("is-on-top");
|
||||
}
|
||||
box.style.left = `${this.props.x}px`;
|
||||
box.style.top = `${this.props.y}px`;
|
||||
|
||||
|
@ -1470,6 +1472,14 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
|
|||
if (!prevProps || prevProps.labelPosition !== this.props.labelPosition) {
|
||||
this.changeLabelPosition(this.props.labelPosition);
|
||||
}
|
||||
//Change z-index class is-on-top
|
||||
if (!prevProps || prevProps.isOnTop !== this.props.isOnTop) {
|
||||
if (this.props.isOnTop) {
|
||||
this.elementRef.classList.add("is-on-top");
|
||||
} else {
|
||||
this.elementRef.classList.remove("is-on-top");
|
||||
}
|
||||
}
|
||||
// Change link.
|
||||
if (
|
||||
prevProps &&
|
||||
|
|
|
@ -318,19 +318,9 @@ export default class VisualConsole {
|
|||
// Force the first render.
|
||||
this.render();
|
||||
|
||||
// Sort by isOnTop, id ASC
|
||||
// Sort by id ASC
|
||||
items = items.sort(function(a, b) {
|
||||
if (
|
||||
a.isOnTop == null ||
|
||||
b.isOnTop == null ||
|
||||
a.id == null ||
|
||||
b.id == null
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a.isOnTop && !b.isOnTop) return 1;
|
||||
else if (!a.isOnTop && b.isOnTop) return -1;
|
||||
if (a.id == null || b.id == null) return 0;
|
||||
else if (a.id > b.id) return 1;
|
||||
else return -1;
|
||||
});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { AnyObject } from "../lib/types";
|
||||
import { parseIntOr, notEmptyStringOr } from "../lib";
|
||||
import { parseIntOr, notEmptyStringOr, t } from "../lib";
|
||||
import Item, { ItemType, ItemProps, itemBasePropsDecoder } from "../Item";
|
||||
import { InputGroup, FormContainer } from "../Form";
|
||||
|
||||
interface BoxProps extends ItemProps {
|
||||
// Overrided properties.
|
||||
|
@ -39,6 +40,95 @@ export function boxPropsDecoder(data: AnyObject): BoxProps | never {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to add item to the Box item form
|
||||
* This item consists of a label and a color type input color.
|
||||
* Element border color is stored in the borderColor property
|
||||
*/
|
||||
class BorderColorInputGroup extends InputGroup<Partial<BoxProps>> {
|
||||
protected createContent(): HTMLElement | HTMLElement[] {
|
||||
const borderColorLabel = document.createElement("label");
|
||||
borderColorLabel.textContent = t("Border color");
|
||||
|
||||
const borderColorInput = document.createElement("input");
|
||||
borderColorInput.type = "color";
|
||||
borderColorInput.required = true;
|
||||
|
||||
borderColorInput.value = `${this.currentData.borderColor ||
|
||||
this.initialData.borderColor ||
|
||||
"#000000"}`;
|
||||
|
||||
borderColorInput.addEventListener("change", e => {
|
||||
this.updateData({
|
||||
borderColor: (e.target as HTMLInputElement).value
|
||||
});
|
||||
});
|
||||
|
||||
borderColorLabel.appendChild(borderColorInput);
|
||||
|
||||
return borderColorLabel;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to add item to the Box item form
|
||||
* This item consists of a label and a color type input number.
|
||||
* Element border width is stored in the borderWidth property
|
||||
*/
|
||||
class BorderWidthInputGroup extends InputGroup<Partial<BoxProps>> {
|
||||
protected createContent(): HTMLElement | HTMLElement[] {
|
||||
const borderWidthLabel = document.createElement("label");
|
||||
borderWidthLabel.textContent = t("Border Width");
|
||||
|
||||
const borderWidthInput = document.createElement("input");
|
||||
borderWidthInput.type = "number";
|
||||
borderWidthInput.min = "0";
|
||||
borderWidthInput.required = true;
|
||||
borderWidthInput.value = `${this.currentData.borderWidth ||
|
||||
this.initialData.borderWidth ||
|
||||
0}`;
|
||||
borderWidthInput.addEventListener("change", e =>
|
||||
this.updateData({
|
||||
borderWidth: parseIntOr((e.target as HTMLInputElement).value, 0)
|
||||
})
|
||||
);
|
||||
|
||||
borderWidthLabel.appendChild(borderWidthInput);
|
||||
|
||||
return borderWidthLabel;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to add item to the Box item form
|
||||
* This item consists of a label and a color type input color.
|
||||
* Element fill color is stored in the fillcolor property
|
||||
*/
|
||||
class FillColorInputGroup extends InputGroup<Partial<BoxProps>> {
|
||||
protected createContent(): HTMLElement | HTMLElement[] {
|
||||
const fillColorLabel = document.createElement("label");
|
||||
fillColorLabel.textContent = t("Fill color");
|
||||
|
||||
const fillColorInput = document.createElement("input");
|
||||
fillColorInput.type = "color";
|
||||
fillColorInput.required = true;
|
||||
|
||||
fillColorInput.value = `${this.currentData.fillColor ||
|
||||
this.initialData.fillColor ||
|
||||
"#000000"}`;
|
||||
|
||||
fillColorInput.addEventListener("change", e => {
|
||||
this.updateData({
|
||||
fillColor: (e.target as HTMLInputElement).value
|
||||
});
|
||||
});
|
||||
|
||||
fillColorLabel.appendChild(fillColorInput);
|
||||
|
||||
return fillColorLabel;
|
||||
}
|
||||
}
|
||||
|
||||
export default class Box extends Item<BoxProps> {
|
||||
protected createDomElement(): HTMLElement {
|
||||
const box: HTMLDivElement = document.createElement("div");
|
||||
|
@ -65,4 +155,46 @@ export default class Box extends Item<BoxProps> {
|
|||
|
||||
return box;
|
||||
}
|
||||
|
||||
/**
|
||||
* To update the content element.
|
||||
* @override Item.updateDomElement
|
||||
*/
|
||||
protected updateDomElement(element: HTMLElement): void {
|
||||
if (this.props.fillColor) {
|
||||
element.style.backgroundColor = this.props.fillColor;
|
||||
}
|
||||
|
||||
// Border.
|
||||
if (this.props.borderWidth > 0) {
|
||||
element.style.borderStyle = "solid";
|
||||
// Control the max width to prevent this item to expand beyond its parent.
|
||||
const maxBorderWidth = Math.min(this.props.width, this.props.height) / 2;
|
||||
const borderWidth = Math.min(this.props.borderWidth, maxBorderWidth);
|
||||
element.style.borderWidth = `${borderWidth}px`;
|
||||
|
||||
if (this.props.borderColor) {
|
||||
element.style.borderColor = this.props.borderColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @override function to add or remove inputsGroups those that are not necessary.
|
||||
* Add to:
|
||||
* LinkConsoleInputGroup
|
||||
*/
|
||||
public getFormContainer(): FormContainer {
|
||||
const formContainer = super.getFormContainer();
|
||||
formContainer.addInputGroup(
|
||||
new BorderColorInputGroup("border-color", this.props)
|
||||
);
|
||||
formContainer.addInputGroup(
|
||||
new BorderWidthInputGroup("border-width", this.props)
|
||||
);
|
||||
formContainer.addInputGroup(
|
||||
new FillColorInputGroup("fill-width", this.props)
|
||||
);
|
||||
return formContainer;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,18 +3,26 @@ import {
|
|||
LinkedVisualConsoleProps,
|
||||
AnyObject
|
||||
} from "../lib/types";
|
||||
import { modulePropsDecoder, linkedVCPropsDecoder } from "../lib";
|
||||
import { modulePropsDecoder, linkedVCPropsDecoder, t } from "../lib";
|
||||
import Item, {
|
||||
itemBasePropsDecoder,
|
||||
ItemType,
|
||||
ItemProps,
|
||||
LinkConsoleInputGroup
|
||||
} from "../Item";
|
||||
import { FormContainer } from "../Form";
|
||||
import { FormContainer, InputGroup } from "../Form";
|
||||
import fontAwesomeIcon from "../lib/FontAwesomeIcon";
|
||||
import { faTrashAlt, faPlusCircle } from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
export type ColorCloudProps = {
|
||||
type: ItemType.COLOR_CLOUD;
|
||||
color: string;
|
||||
defaultColor: string;
|
||||
colorRanges: {
|
||||
color: string;
|
||||
fromValue: number;
|
||||
toValue: number;
|
||||
}[];
|
||||
// TODO: Add the rest of the color cloud values?
|
||||
} & ItemProps &
|
||||
WithModuleProps &
|
||||
|
@ -41,11 +49,292 @@ export function colorCloudPropsDecoder(
|
|||
...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.
|
||||
type: ItemType.COLOR_CLOUD,
|
||||
color: data.color,
|
||||
defaultColor: data.defaultColor,
|
||||
colorRanges: data.colorRanges,
|
||||
...modulePropsDecoder(data), // Object spread. It will merge the properties of the two objects.
|
||||
...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to add item to the Color cloud item form
|
||||
* This item consists of a label and a color type input color.
|
||||
* Element default color is stored in the color property
|
||||
*/
|
||||
class ColorInputGroup extends InputGroup<Partial<ColorCloudProps>> {
|
||||
protected createContent(): HTMLElement | HTMLElement[] {
|
||||
const ColorLabel = document.createElement("label");
|
||||
ColorLabel.textContent = t("Default color");
|
||||
|
||||
const ColorInput = document.createElement("input");
|
||||
ColorInput.type = "color";
|
||||
ColorInput.required = true;
|
||||
|
||||
ColorInput.value = `${this.currentData.defaultColor ||
|
||||
this.initialData.defaultColor ||
|
||||
"#000000"}`;
|
||||
|
||||
ColorInput.addEventListener("change", e => {
|
||||
this.updateData({
|
||||
defaultColor: (e.target as HTMLInputElement).value
|
||||
});
|
||||
});
|
||||
|
||||
ColorLabel.appendChild(ColorInput);
|
||||
|
||||
return ColorLabel;
|
||||
}
|
||||
}
|
||||
|
||||
type ColorRanges = ColorCloudProps["colorRanges"];
|
||||
type ColorRange = ColorRanges[0];
|
||||
|
||||
class RangesInputGroup extends InputGroup<Partial<ColorCloudProps>> {
|
||||
protected createContent(): HTMLElement | HTMLElement[] {
|
||||
const rangesLabel = this.createLabel("Ranges");
|
||||
const rangesControlsContainer = document.createElement("div");
|
||||
const createdRangesContainer = document.createElement("div");
|
||||
|
||||
rangesControlsContainer.appendChild(createdRangesContainer);
|
||||
rangesLabel.appendChild(rangesControlsContainer);
|
||||
|
||||
const colorRanges =
|
||||
this.currentData.colorRanges || this.initialData.colorRanges || [];
|
||||
|
||||
let buildRanges: (ranges: ColorRanges) => void;
|
||||
|
||||
const handleRangeUpdatePartial = (index: number) => (
|
||||
range: ColorRange
|
||||
): void => {
|
||||
const colorRanges =
|
||||
this.currentData.colorRanges || this.initialData.colorRanges || [];
|
||||
this.updateData({
|
||||
colorRanges: [
|
||||
...colorRanges.slice(0, index),
|
||||
range,
|
||||
...colorRanges.slice(index)
|
||||
]
|
||||
});
|
||||
};
|
||||
|
||||
const handleDelete = (index: number) => () => {
|
||||
const colorRanges =
|
||||
this.currentData.colorRanges || this.initialData.colorRanges || [];
|
||||
const newRanges = [
|
||||
...colorRanges.slice(0, index),
|
||||
...colorRanges.slice(index + 1)
|
||||
];
|
||||
|
||||
this.updateData({
|
||||
colorRanges: newRanges
|
||||
});
|
||||
buildRanges(newRanges);
|
||||
};
|
||||
|
||||
const handleCreate = (range: ColorRange): void => {
|
||||
const colorRanges =
|
||||
this.currentData.colorRanges || this.initialData.colorRanges || [];
|
||||
const newRanges = [...colorRanges, range];
|
||||
this.updateData({
|
||||
colorRanges: newRanges
|
||||
});
|
||||
buildRanges(newRanges);
|
||||
};
|
||||
|
||||
buildRanges = ranges => {
|
||||
createdRangesContainer.innerHTML = "";
|
||||
console.log(ranges);
|
||||
ranges.forEach((colorRange, index) =>
|
||||
createdRangesContainer.appendChild(
|
||||
this.rangeContainer(
|
||||
colorRange,
|
||||
handleRangeUpdatePartial(index),
|
||||
handleDelete(index)
|
||||
)
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
buildRanges(colorRanges);
|
||||
|
||||
rangesControlsContainer.appendChild(
|
||||
this.initialRangeContainer(handleCreate)
|
||||
);
|
||||
|
||||
return rangesLabel;
|
||||
}
|
||||
|
||||
private initialRangeContainer(onCreate: (range: ColorRange) => void) {
|
||||
// TODO: Document
|
||||
const initialState = { color: "#fff" };
|
||||
const state: Partial<ColorRange> = initialState;
|
||||
|
||||
const handleFromValue = (value: ColorRange["fromValue"]): void => {
|
||||
state.fromValue = value;
|
||||
};
|
||||
const handleToValue = (value: ColorRange["toValue"]): void => {
|
||||
state.toValue = value;
|
||||
};
|
||||
const handleColor = (value: ColorRange["color"]): void => {
|
||||
state.color = value;
|
||||
};
|
||||
|
||||
// User defined type guard.
|
||||
// Docs: https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards
|
||||
const isValid = (range: Partial<ColorRange>): range is ColorRange =>
|
||||
typeof range.color !== "undefined" &&
|
||||
typeof range.toValue !== "undefined" &&
|
||||
typeof range.fromValue !== "undefined";
|
||||
|
||||
const handleCreate = () => {
|
||||
if (isValid(state)) onCreate(state);
|
||||
};
|
||||
|
||||
const rangesContainer = document.createElement("div");
|
||||
|
||||
// Div From value.
|
||||
const rangesContainerFromValue = document.createElement("div");
|
||||
const rangesLabelFromValue = this.createLabel("From Value");
|
||||
const rangesInputFromValue = this.createInputNumber(null, handleFromValue);
|
||||
rangesContainerFromValue.appendChild(rangesLabelFromValue);
|
||||
rangesContainerFromValue.appendChild(rangesInputFromValue);
|
||||
rangesContainer.appendChild(rangesContainerFromValue);
|
||||
|
||||
// Div To Value.
|
||||
const rangesDivContainerToValue = document.createElement("div");
|
||||
const rangesLabelToValue = this.createLabel("To Value");
|
||||
const rangesInputToValue = this.createInputNumber(null, handleToValue);
|
||||
rangesContainerFromValue.appendChild(rangesLabelToValue);
|
||||
rangesContainerFromValue.appendChild(rangesInputToValue);
|
||||
rangesContainer.appendChild(rangesDivContainerToValue);
|
||||
|
||||
// Div Color.
|
||||
const rangesDivContainerColor = document.createElement("div");
|
||||
const rangesLabelColor = this.createLabel("Color");
|
||||
const rangesInputColor = this.createInputColor(
|
||||
initialState.color,
|
||||
handleColor
|
||||
);
|
||||
rangesContainerFromValue.appendChild(rangesLabelColor);
|
||||
rangesContainerFromValue.appendChild(rangesInputColor);
|
||||
rangesContainer.appendChild(rangesDivContainerColor);
|
||||
|
||||
// Button delete.
|
||||
const createBtn = document.createElement("a");
|
||||
createBtn.appendChild(
|
||||
fontAwesomeIcon(faPlusCircle, t("Create color range"))
|
||||
);
|
||||
createBtn.addEventListener("click", handleCreate);
|
||||
|
||||
rangesContainer.appendChild(createBtn);
|
||||
|
||||
return rangesContainer;
|
||||
}
|
||||
|
||||
private rangeContainer(
|
||||
colorRange: ColorRange,
|
||||
onUpdate: (range: ColorRange) => void,
|
||||
onDelete: () => void
|
||||
): HTMLDivElement {
|
||||
// TODO: Document
|
||||
const state = { ...colorRange };
|
||||
|
||||
const handleFromValue = (value: ColorRange["fromValue"]): void => {
|
||||
state.fromValue = value;
|
||||
onUpdate({ ...state });
|
||||
};
|
||||
const handleToValue = (value: ColorRange["toValue"]): void => {
|
||||
state.toValue = value;
|
||||
onUpdate({ ...state });
|
||||
};
|
||||
const handleColor = (value: ColorRange["color"]): void => {
|
||||
state.color = value;
|
||||
onUpdate({ ...state });
|
||||
};
|
||||
|
||||
const rangesContainer = document.createElement("div");
|
||||
|
||||
// Div From value.
|
||||
const rangesContainerFromValue = document.createElement("div");
|
||||
const rangesLabelFromValue = this.createLabel("From Value");
|
||||
const rangesInputFromValue = this.createInputNumber(
|
||||
colorRange.fromValue,
|
||||
handleFromValue
|
||||
);
|
||||
rangesContainerFromValue.appendChild(rangesLabelFromValue);
|
||||
rangesContainerFromValue.appendChild(rangesInputFromValue);
|
||||
rangesContainer.appendChild(rangesContainerFromValue);
|
||||
|
||||
// Div To Value.
|
||||
const rangesDivContainerToValue = document.createElement("div");
|
||||
const rangesLabelToValue = this.createLabel("To Value");
|
||||
const rangesInputToValue = this.createInputNumber(
|
||||
colorRange.toValue,
|
||||
handleToValue
|
||||
);
|
||||
rangesContainerFromValue.appendChild(rangesLabelToValue);
|
||||
rangesContainerFromValue.appendChild(rangesInputToValue);
|
||||
rangesContainer.appendChild(rangesDivContainerToValue);
|
||||
|
||||
// Div Color.
|
||||
const rangesDivContainerColor = document.createElement("div");
|
||||
const rangesLabelColor = this.createLabel("Color");
|
||||
const rangesInputColor = this.createInputColor(
|
||||
colorRange.color,
|
||||
handleColor
|
||||
);
|
||||
rangesContainerFromValue.appendChild(rangesLabelColor);
|
||||
rangesContainerFromValue.appendChild(rangesInputColor);
|
||||
rangesContainer.appendChild(rangesDivContainerColor);
|
||||
|
||||
// Button delete.
|
||||
const deleteBtn = document.createElement("a");
|
||||
deleteBtn.appendChild(fontAwesomeIcon(faTrashAlt, t("Delete color range")));
|
||||
deleteBtn.addEventListener("click", onDelete);
|
||||
|
||||
rangesContainer.appendChild(deleteBtn);
|
||||
|
||||
return rangesContainer;
|
||||
}
|
||||
|
||||
private createLabel(text: string): HTMLLabelElement {
|
||||
const label = document.createElement("label");
|
||||
label.textContent = t(text);
|
||||
return label;
|
||||
}
|
||||
|
||||
private createInputNumber(
|
||||
value: number | null,
|
||||
onUpdate: (value: number) => void
|
||||
): HTMLInputElement {
|
||||
const input = document.createElement("input");
|
||||
input.type = "number";
|
||||
input.required = true;
|
||||
if (value !== null) input.value = `${value}`;
|
||||
input.addEventListener("change", e => {
|
||||
const value = parseInt((e.target as HTMLInputElement).value);
|
||||
if (!isNaN(value)) onUpdate(value);
|
||||
});
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
private createInputColor(
|
||||
value: string | null,
|
||||
onUpdate: (value: string) => void
|
||||
): HTMLInputElement {
|
||||
const input = document.createElement("input");
|
||||
input.type = "color";
|
||||
input.required = true;
|
||||
if (value !== null) input.value = value;
|
||||
input.addEventListener("change", e =>
|
||||
onUpdate((e.target as HTMLInputElement).value)
|
||||
);
|
||||
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
const svgNS = "http://www.w3.org/2000/svg";
|
||||
|
||||
export default class ColorCloud extends Item<ColorCloudProps> {
|
||||
|
@ -112,12 +401,18 @@ export default class ColorCloud extends Item<ColorCloudProps> {
|
|||
* @override function to add or remove inputsGroups those that are not necessary.
|
||||
* Add to:
|
||||
* LinkConsoleInputGroup
|
||||
* ColorInputGroup
|
||||
* RangesInputGroup
|
||||
*/
|
||||
public getFormContainer(): FormContainer {
|
||||
const formContainer = super.getFormContainer();
|
||||
formContainer.addInputGroup(
|
||||
new LinkConsoleInputGroup("link-console", this.props)
|
||||
);
|
||||
formContainer.addInputGroup(new ColorInputGroup("color-cloud", this.props));
|
||||
formContainer.addInputGroup(
|
||||
new RangesInputGroup("ranges-cloud", this.props)
|
||||
);
|
||||
return formContainer;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,15 +5,17 @@ import {
|
|||
notEmptyStringOr,
|
||||
stringIsEmpty,
|
||||
decodeBase64,
|
||||
parseBoolean
|
||||
parseBoolean,
|
||||
t
|
||||
} from "../lib";
|
||||
import Item, {
|
||||
ItemProps,
|
||||
itemBasePropsDecoder,
|
||||
ItemType,
|
||||
LinkConsoleInputGroup
|
||||
LinkConsoleInputGroup,
|
||||
ImageInputGroup
|
||||
} from "../Item";
|
||||
import { FormContainer } from "../Form";
|
||||
import { FormContainer, InputGroup } from "../Form";
|
||||
|
||||
export type GroupProps = {
|
||||
type: ItemType.GROUP_ITEM;
|
||||
|
@ -66,6 +68,39 @@ export function groupPropsDecoder(data: AnyObject): GroupProps | never {
|
|||
};
|
||||
}
|
||||
|
||||
// TODO: Document
|
||||
class ShowStatisticsInputGroup extends InputGroup<Partial<GroupProps>> {
|
||||
protected createContent(): HTMLElement | HTMLElement[] {
|
||||
const showStatisticsLabel = document.createElement("label");
|
||||
showStatisticsLabel.textContent = t("Show statistics");
|
||||
|
||||
const showStatisticsInputChkbx = document.createElement("input");
|
||||
showStatisticsInputChkbx.id = "checkbox-switch";
|
||||
showStatisticsInputChkbx.className = "checkbox-switch";
|
||||
showStatisticsInputChkbx.type = "checkbox";
|
||||
showStatisticsInputChkbx.name = "checkbox-enable-link";
|
||||
showStatisticsInputChkbx.value = "1";
|
||||
showStatisticsInputChkbx.checked =
|
||||
this.currentData.showStatistics ||
|
||||
this.initialData.showStatistics ||
|
||||
false;
|
||||
showStatisticsInputChkbx.addEventListener("change", e =>
|
||||
this.updateData({
|
||||
showStatistics: (e.target as HTMLInputElement).checked
|
||||
})
|
||||
);
|
||||
|
||||
const linkInputLabel = document.createElement("label");
|
||||
linkInputLabel.className = "label-switch";
|
||||
linkInputLabel.htmlFor = "checkbox-switch";
|
||||
|
||||
showStatisticsLabel.appendChild(showStatisticsInputChkbx);
|
||||
showStatisticsLabel.appendChild(linkInputLabel);
|
||||
|
||||
return showStatisticsLabel;
|
||||
}
|
||||
}
|
||||
|
||||
export default class Group extends Item<GroupProps> {
|
||||
protected createDomElement(): HTMLElement {
|
||||
const element = document.createElement("div");
|
||||
|
@ -73,7 +108,8 @@ export default class Group extends Item<GroupProps> {
|
|||
|
||||
if (!this.props.showStatistics && this.props.statusImageSrc !== null) {
|
||||
// Icon with status.
|
||||
element.style.background = `url(${this.props.statusImageSrc}) no-repeat`;
|
||||
element.style.backgroundImage = `url(${this.props.statusImageSrc})`;
|
||||
element.style.backgroundRepeat = "no-repeat";
|
||||
element.style.backgroundSize = "contain";
|
||||
element.style.backgroundPosition = "center";
|
||||
} else if (this.props.showStatistics && this.props.html != null) {
|
||||
|
@ -84,16 +120,46 @@ export default class Group extends Item<GroupProps> {
|
|||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* To update the content element.
|
||||
* @override Item.updateDomElement
|
||||
*/
|
||||
protected updateDomElement(element: HTMLElement): void {
|
||||
if (!this.props.showStatistics && this.props.statusImageSrc !== null) {
|
||||
// Icon with status.
|
||||
element.style.backgroundImage = `url(${this.props.statusImageSrc})`;
|
||||
element.style.backgroundRepeat = "no-repeat";
|
||||
element.style.backgroundSize = "contain";
|
||||
element.style.backgroundPosition = "center";
|
||||
element.innerHTML = "";
|
||||
} else if (this.props.showStatistics && this.props.html != null) {
|
||||
// Stats table.
|
||||
element.innerHTML = this.props.html;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @override function to add or remove inputsGroups those that are not necessary.
|
||||
* Add to:
|
||||
* LinkConsoleInputGroup
|
||||
* ImageInputGroup
|
||||
* ShowStatisticsInputGroup
|
||||
*/
|
||||
public getFormContainer(): FormContainer {
|
||||
const formContainer = super.getFormContainer();
|
||||
formContainer.addInputGroup(
|
||||
new LinkConsoleInputGroup("link-console", this.props)
|
||||
);
|
||||
formContainer.addInputGroup(
|
||||
new ImageInputGroup("image-console", {
|
||||
...this.props,
|
||||
imageKey: "imageSrc",
|
||||
showStatusImg: true
|
||||
})
|
||||
);
|
||||
formContainer.addInputGroup(
|
||||
new ShowStatisticsInputGroup("show-statistic", this.props)
|
||||
);
|
||||
return formContainer;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,11 @@
|
|||
justify-items: center;
|
||||
align-items: center;
|
||||
user-select: text;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.visual-console-item.is-on-top {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.visual-console-item.is-editing {
|
||||
|
|
Loading…
Reference in New Issue