Merge branch 'ent-9160-selector-de-elementos-multiple-en-consola-visual' into 'develop'

Ent 9160 selector de elementos multiple en consola visual

See merge request artica/pandorafms!6367
This commit is contained in:
Gorka Sanchez 2023-08-31 06:46:16 +00:00
commit d2b768c8cf
12 changed files with 215 additions and 11 deletions

View File

@ -727,6 +727,13 @@ div.module-graph .gauge_d3_class {
background: #82b92e; background: #82b92e;
} }
#box-rectangle-selection {
position: absolute;
width: 0px;
height: 0px;
border: 2px solid #002f33;
}
/* Styles for the solid icons */ /* Styles for the solid icons */
.fa { .fa {

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

@ -693,6 +693,14 @@ ui_require_css_file('form');
var baseUrl = "<?php echo ui_get_full_url('/', false, false, false); ?>"; var baseUrl = "<?php echo ui_get_full_url('/', false, false, false); ?>";
var controls = document.getElementById('vc-controls'); var controls = document.getElementById('vc-controls');
// Rectangle selections.
window.selection_rectangle = [0, 0, 0, 0];
window.key_multiple_selection = 17; // CTRL key.
window.flag_multiple_selection = false;
window.mousedown = false;
window.starX = 0;
window.starY = 0;
autoHideElement(controls, 1000); autoHideElement(controls, 1000);
var handleUpdate = function (prevProps, newProps) { var handleUpdate = function (prevProps, newProps) {
if (!newProps) return; if (!newProps) return;
@ -822,6 +830,8 @@ ui_require_css_file('form');
} }
} }
$('body').append('<div id="box-rectangle-selection"></div>');
<?php <?php
if ($edit_capable === true) { if ($edit_capable === true) {
?> ?>
@ -983,6 +993,111 @@ if ($edit_capable === true) {
} }
}); });
}); });
$(document).keydown(function(e) {
const edit = $("input[name=edit-mode]").prop('checked');
if (e.keyCode == key_multiple_selection && edit === true) {
flag_multiple_selection = true;
}
});
$("#visual-console-container").mousedown(function(e) {
if (flag_multiple_selection === true &&
e.target.classList.contains("visual-console-item") === false
) {
$('selector').css('cursor', 'crosshair');
document.documentElement.style.cursor = 'crosshair';
mousedown = true;
// Star position.
var rect = document.getElementById('visual-console-container').getBoundingClientRect();
starX = (e.clientX - rect.left) + rect.x;
starY = (e.clientY - rect.top) + rect.y;
$("#box-rectangle-selection").css("top", starY + 'px');
$("#box-rectangle-selection").css("left", starX + 'px');
$("#box-rectangle-selection").css("display", '');
}
});
$(document).mousemove(function(e) {
if (flag_multiple_selection === true && mousedown === true) {
var rect = document.getElementById('visual-console-container').getBoundingClientRect();
var xMouse = (e.clientX - rect.left) + rect.x;
var yMouse = (e.clientY - rect.top) + rect.y;
var x = starX;
var width = xMouse - starX;
if (width < 0) {
x = xMouse;
width = starX - xMouse;
}
var y = starY;
var height = yMouse - starY;
if (height < 0) {
y = yMouse;
height = starY - yMouse;
}
if (xMouse >= rect.x && yMouse >= rect.y &&
xMouse < (rect.x + rect.width) &&
yMouse < (rect.y + rect.height)
) {
$("#box-rectangle-selection").css("top", y + 'px');
$("#box-rectangle-selection").css("left", x + 'px');
$("#box-rectangle-selection").css("width", width + 'px');
$("#box-rectangle-selection").css("height", height + 'px');
var r2 = new Rectangle();
r2.left = x;
r2.top = y;
r2.right = x + width;
r2.bottom = y + height;
visualConsoleManager.visualConsole.elements.forEach(item => {
// Calcular puntos arriba a la izquierda y abajo a la derecha de ambos rectangulos.
var r1 = new Rectangle();
r1.left = item.itemProps.x + rect.x;
r1.top = item.itemProps.y + rect.y;
r1.right = item.itemProps.x + rect.x + item.itemProps.width;
r1.bottom = item.itemProps.y + rect.y + item.itemProps.height;
if (intersectRect(r1, r2)) {
if (item.meta.isSelected === false) {
item.selectItem();
}
}
});
}
}
});
$("#visual-console-container").mouseup(function(e) {
if (flag_multiple_selection === true) {
document.documentElement.style.cursor = 'default';
mousedown = false;
}
$("#box-rectangle-selection").css("width", '0px');
$("#box-rectangle-selection").css("height", '0px');
$("#box-rectangle-selection").css("display", 'none');
});
$(document).keyup(function(e) {
const edit = $("input[name=edit-mode]").prop('checked');
if (e.keyCode == key_multiple_selection && edit === true) {
flag_multiple_selection = false;
document.documentElement.style.cursor = 'default';
mousedown = false;
$("#box-rectangle-selection").css("width", '0px');
$("#box-rectangle-selection").css("height", '0px');
$("#box-rectangle-selection").css("display", 'none');
}
});
<?php <?php
} }
?> ?>
@ -1086,6 +1201,22 @@ if ($edit_capable === true) {
visualConsoleManager.forceUpdateVisualConsole(); visualConsoleManager.forceUpdateVisualConsole();
} }
function intersectRect(r1, r2) {
return !(r2.left > r1.right ||
r2.right < r1.left ||
r2.top > r1.bottom ||
r2.bottom < r1.top);
}
class Rectangle {
constructor(val) {
this.left = val;
this.top = val;
this.right = val;
this.bottom = val;
}
}
/** /**
* Process ajax responses and shows a dialog with results. * Process ajax responses and shows a dialog with results.
*/ */

View File

@ -274,7 +274,7 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
// This function will only run the 2nd arg function after the time // This function will only run the 2nd arg function after the time
// of the first arg have passed after its last execution. // of the first arg have passed after its last execution.
private debouncedMovementSave = debounce( public debouncedMovementSave = debounce(
500, // ms. 500, // ms.
(x: Position["x"], y: Position["y"]) => { (x: Position["x"], y: Position["y"]) => {
// Update the metadata information. // Update the metadata information.
@ -363,7 +363,7 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
// This function will only run the 2nd arg function after the time // This function will only run the 2nd arg function after the time
// of the first arg have passed after its last execution. // of the first arg have passed after its last execution.
private debouncedResizementSave = debounce( public debouncedResizementSave = debounce(
500, // ms. 500, // ms.
(width: Size["width"], height: Size["height"]) => { (width: Size["width"], height: Size["height"]) => {
// Update the metadata information. // Update the metadata information.
@ -1043,7 +1043,7 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
* @param x Horizontal axis position. * @param x Horizontal axis position.
* @param y Vertical axis position. * @param y Vertical axis position.
*/ */
protected moveElement(x: number, y: number): void { public moveElement(x: number, y: number): void {
this.elementRef.style.left = `${x}px`; this.elementRef.style.left = `${x}px`;
this.elementRef.style.top = `${y}px`; this.elementRef.style.top = `${y}px`;
} }
@ -1080,7 +1080,7 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
* @param width * @param width
* @param height * @param height
*/ */
protected resizeElement(width: number, height: number): void { public resizeElement(width: number, height: number): void {
// The most valuable size is the content size. // The most valuable size is the content size.
if ( if (
this.props.type != ItemType.LINE_ITEM && this.props.type != ItemType.LINE_ITEM &&

View File

@ -286,6 +286,44 @@ export default class VisualConsole {
*/ */
private handleElementMovement: (e: ItemMovedEvent) => void = e => { private handleElementMovement: (e: ItemMovedEvent) => void = e => {
var type = e.item.itemProps.type; var type = e.item.itemProps.type;
if (
type !== 13 &&
type !== 21 &&
(typeof this.props.gridSelected === "undefined" ||
this.props.gridSelected === false)
) {
this.elements.forEach(item => {
if (
item.meta.isSelected === true &&
e.item.itemProps.id !== item.itemProps.id &&
item.props.type !== 13 &&
item.props.type !== 21
) {
const movement_x = e.newPosition.x - e.item.props.x;
const movement_y = e.newPosition.y - e.item.props.y;
let newX = item.props.x + movement_x;
let newY = item.props.y + movement_y;
if (newX > this.props.width) {
newX = this.props.width;
} else if (newX <= 0) {
newX = 0;
}
if (newY > this.props.height) {
newY = this.props.height;
} else if (newY <= 0) {
newY = 0;
}
item.moveElement(newX, newY);
item.debouncedMovementSave(newX, newY);
}
});
}
if (type !== 13 && type !== 21 && this.props.gridSelected === true) { if (type !== 13 && type !== 21 && this.props.gridSelected === true) {
var gridSize = this.props.gridSize; var gridSize = this.props.gridSize;
var positionX = e.newPosition.x; var positionX = e.newPosition.x;
@ -386,6 +424,27 @@ export default class VisualConsole {
* @param e Event object. * @param e Event object.
*/ */
private handleElementResizement: (e: ItemResizedEvent) => void = e => { private handleElementResizement: (e: ItemResizedEvent) => void = e => {
if (
e.item.props.type !== 13 &&
e.item.props.type !== 21 &&
(typeof this.props.gridSelected === "undefined" ||
this.props.gridSelected === false)
) {
this.elements.forEach(item => {
if (
item.meta.isSelected === true &&
e.item.itemProps.id !== item.itemProps.id &&
item.props.type !== 13 &&
item.props.type !== 21
) {
item.setMeta({ isUpdating: true });
// Resize the DOM element.
item.resizeElement(e.newSize.width, e.newSize.height);
// Run the save function.
item.debouncedResizementSave(e.newSize.width, e.newSize.height);
}
});
}
// Move their relation lines. // Move their relation lines.
const item = e.item; const item = e.item;
const props = item.props; const props = item.props;

View File

@ -197,7 +197,7 @@ export default class Clock extends Item<ClockProps> {
* @param width * @param width
* @param height * @param height
*/ */
protected resizeElement(width: number, height: number): void { public resizeElement(width: number, height: number): void {
// Destructuring assigment: http://es6-features.org/#ObjectMatchingShorthandNotation // Destructuring assigment: http://es6-features.org/#ObjectMatchingShorthandNotation
const { width: newWidth, height: newHeight } = this.getElementSize( const { width: newWidth, height: newHeight } = this.getElementSize(
width, width,

View File

@ -363,7 +363,7 @@ export default class ColorCloud extends Item<ColorCloudProps> {
return container; return container;
} }
protected resizeElement(width: number): void { public resizeElement(width: number): void {
super.resizeElement(width, width); super.resizeElement(width, width);
} }

View File

@ -271,7 +271,7 @@ export default class Odometer extends Item<OdometerProps> {
}, 500); }, 500);
} }
protected resizeElement(width: number): void { public resizeElement(width: number): void {
super.resizeElement(width, width / 2); super.resizeElement(width, width / 2);
} }

View File

@ -288,7 +288,7 @@ export default class Percentile extends Item<PercentileProps> {
* To update the content element. * To update the content element.
* @override Item.updateDomElement * @override Item.updateDomElement
*/ */
protected resizeElement(width: number, height: number): void { public resizeElement(width: number, height: number): void {
if (this.props.percentileType === "progress-bar") { if (this.props.percentileType === "progress-bar") {
super.resizeElement(width, 35); super.resizeElement(width, 35);
} else { } else {

View File

@ -726,3 +726,10 @@ div.module-graph .gauge_d3_class {
.green_background { .green_background {
background: #82b92e; background: #82b92e;
} }
#box-rectangle-selection {
position: absolute;
width: 0px;
height: 0px;
border: 2px solid #002f33;
}