From 506746262027120c57d5f60426e743eb22189f4a Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Thu, 25 Jul 2019 17:58:37 +0200 Subject: [PATCH] Added remove item --- .../javascript/pandora_visual_console.js | 120 +++++++++++++++++- pandora_console/include/rest-api/index.php | 8 ++ .../include/rest-api/models/Model.php | 12 ++ .../models/VisualConsole/Container.php | 15 +++ .../rest-api/models/VisualConsole/Item.php | 27 ++++ .../include/styles/visual_maps.css | 2 +- .../operation/visual_console/view.php | 36 ++++++ visual_console_client/src/Item.ts | 12 +- visual_console_client/src/VisualConsole.ts | 38 +++++- 9 files changed, 257 insertions(+), 13 deletions(-) diff --git a/pandora_console/include/javascript/pandora_visual_console.js b/pandora_console/include/javascript/pandora_visual_console.js index cb1403d081..ebbd12e914 100755 --- a/pandora_console/include/javascript/pandora_visual_console.js +++ b/pandora_console/include/javascript/pandora_visual_console.js @@ -133,7 +133,11 @@ function createVisualConsole( visualConsole.unselectItem(data.id); } else { // Unselect the rest of the elements if the - visualConsole.selectItem(data.id, !e.nativeEvent.metaKey); + var isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0; + visualConsole.selectItem( + data.id, + isMac ? !e.nativeEvent.metaKey : !e.nativeEvent.ctrlKey + ); } } else if ( !meta.editMode && @@ -358,6 +362,52 @@ function createVisualConsole( .init(); }); + // VC Item remove. + visualConsole.onItemRemove(function(e) { + var id = e.item.props.id; + var data = { + type: e.item.props.type + }; + var taskId = "visual-console-item-update-" + id; + + // Persist the new position. + asyncTaskManager + .add(taskId, function(done) { + var abortable = removeVisualConsoleItem( + baseUrl, + visualConsole.props.id, + id, + data, + function(error, data) { + // if (!error && !data) return; + if (error || !data) { + console.log( + "[ERROR]", + "[VISUAL-CONSOLE-CLIENT]", + "[API]", + error ? error.message : "Invalid response" + ); + + // Move the element to its initial position. + // e.item.move(e.prevPosition.x, e.prevPosition.y); + } + + done(); + } + ); + + return { + cancel: function() { + abortable.abort(); + } + }; + }) + .init(); + // console.log(visualConsole.containerRef); + // console.log(e.item.elementRef); + // Add the item to the DOM. + }); + if (updateInterval != null && updateInterval > 0) { // Start an interval to update the Visual Console. updateVisualConsole(props.id, updateInterval, updateInterval); @@ -620,6 +670,74 @@ function getVisualConsoleItem(baseUrl, vcId, vcItemId, callback) { }; } +/** + * Fetch a Visual Console's structure and its items. + * @param {string} baseUrl Base URL to build the API path. + * @param {number} vcId Identifier of the Visual Console. + * @param {number} vcItemId Identifier of the Visual Console's item. + * @param {function} callback Function to be executed on request success or fail. + * @return {Object} Cancellable. Object which include and .abort([statusText]) function. + */ +// eslint-disable-next-line no-unused-vars +function removeVisualConsoleItem(baseUrl, vcId, vcItemId, data, callback) { + // var apiPath = baseUrl + "/include/rest-api"; + var apiPath = baseUrl + "/ajax.php"; + var jqXHR = null; + + // Cancel the ajax requests. + var abort = function(textStatus) { + if (textStatus == null) textStatus = "abort"; + + // -- XMLHttpRequest.readyState -- + // Value State Description + // 0 UNSENT Client has been created. open() not called yet. + // 4 DONE The operation is complete. + + if (jqXHR.readyState !== 0 && jqXHR.readyState !== 4) + jqXHR.abort(textStatus); + }; + + // Failed request handler. + var handleFail = function(jqXHR, textStatus, errorThrown) { + abort(); + // Manually aborted or not. + if (textStatus === "abort") { + callback(); + } else { + var error = new Error(errorThrown); + error.request = jqXHR; + callback(error); + } + }; + + // Function which handle success case. + var handleSuccess = function(data) { + callback(null, data); + }; + + // Visual Console container request. + jqXHR = jQuery + // .get(apiPath + "/visual-consoles/" + vcId, null, "json") + .get( + apiPath, + { + page: "include/rest-api/index", + removeVisualConsoleItem: 1, + visualConsoleId: vcId, + visualConsoleItemId: vcItemId, + data: data + }, + "json" + ) + .done(handleSuccess) + .fail(handleFail); + + // Abortable. + return { + abort: abort + }; +} + // TODO: Delete the functions below when you can. /************************************** These functions require jQuery library diff --git a/pandora_console/include/rest-api/index.php b/pandora_console/include/rest-api/index.php index e7b16ae82e..c4bcc732b0 100644 --- a/pandora_console/include/rest-api/index.php +++ b/pandora_console/include/rest-api/index.php @@ -15,6 +15,7 @@ $getVisualConsole = (bool) get_parameter('getVisualConsole'); $getVisualConsoleItems = (bool) get_parameter('getVisualConsoleItems'); $updateVisualConsoleItem = (bool) get_parameter('updateVisualConsoleItem'); $getVisualConsoleItem = (bool) get_parameter('getVisualConsoleItem'); +$removeVisualConsoleItem = (bool) get_parameter('removeVisualConsoleItem'); ob_clean(); @@ -109,6 +110,13 @@ if ($getVisualConsole === true) { echo $item; return; } +} else if ($removeVisualConsoleItem === true) { + $itemId = (int) get_parameter('visualConsoleItemId'); + $data = get_parameter('data'); + $class = VisualConsole::getItemClass((int) $data['type']); + $result = $class::delete($itemId); + echo $result; + return; } exit; diff --git a/pandora_console/include/rest-api/models/Model.php b/pandora_console/include/rest-api/models/Model.php index cebdb3d0d7..7568d5edd4 100644 --- a/pandora_console/include/rest-api/models/Model.php +++ b/pandora_console/include/rest-api/models/Model.php @@ -71,6 +71,18 @@ abstract class Model abstract public function save(array $data=[]); + /** + * Delete an item in the database + * + * @param integer $itemId Identifier of the Item. + * + * @return boolean The modeled element data structure stored into the DB. + * + * @abstract + */ + abstract public function delete(int $itemId): bool; + + /** * Constructor of the model. It won't be public. The instances * will be created through factories which start with from*. diff --git a/pandora_console/include/rest-api/models/VisualConsole/Container.php b/pandora_console/include/rest-api/models/VisualConsole/Container.php index 4aff86f066..f5dc992669 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Container.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Container.php @@ -123,6 +123,21 @@ final class Container extends Model } + /** + * Delete an item in the database + * + * @param integer $itemId Identifier of the Item. + * + * @return boolean The modeled element data structure stored into the DB. + * + * @overrides Model::delete. + */ + public function delete(int $itemId): bool + { + return true; + } + + /** * Extract a group Id value. * diff --git a/pandora_console/include/rest-api/models/VisualConsole/Item.php b/pandora_console/include/rest-api/models/VisualConsole/Item.php index 62c8b9678f..eacedaed40 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Item.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Item.php @@ -1667,4 +1667,31 @@ class Item extends CachedModel } + /** + * Delete an item in the database + * + * @param integer $itemId Identifier of the Item. + * + * @return boolean The modeled element data structure stored into the DB. + * + * @overrides Model::delete. + */ + public function delete(int $itemId): bool + { + $result = db_process_sql_delete( + 'tlayout_data', + ['id' => $itemId] + ); + + if ($result) { + db_process_sql_delete( + 'tvisual_console_elements_cache', + ['vc_item_id' => $itemId] + ); + } + + return (bool) $result; + } + + } diff --git a/pandora_console/include/styles/visual_maps.css b/pandora_console/include/styles/visual_maps.css index ee2e6dc49b..b6a2ebf5e2 100644 --- a/pandora_console/include/styles/visual_maps.css +++ b/pandora_console/include/styles/visual_maps.css @@ -51,7 +51,7 @@ input.vs_button_ghost { margin-top: 13px; } input.visual_editor_button_toolbox { - padding-right: 15px; + padding-right: 5px; padding-top: 10px; margin-top: 5px; } diff --git a/pandora_console/operation/visual_console/view.php b/pandora_console/operation/visual_console/view.php index 70ec040973..fd26771252 100644 --- a/pandora_console/operation/visual_console/view.php +++ b/pandora_console/operation/visual_console/view.php @@ -164,7 +164,28 @@ if ($pure === false) { echo html_print_checkbox_switch('edit-mode', 1, false, true); echo ''; echo ''; + echo ''; echo '
'; + // sub visual_editor_button_toolbox delete_item delete_min } echo '
'; @@ -340,9 +361,11 @@ $visualConsoleItems = VisualConsole::getItemsFromDB( if ($(this).prop('checked')) { visualConsoleManager.visualConsole.enableEditMode(); visualConsoleManager.changeUpdateInterval(0); + $('#prueba').css('visibility', ''); } else { visualConsoleManager.visualConsole.disableEditMode(); visualConsoleManager.changeUpdateInterval(); // To ms. + $('#prueba').css('visibility', 'hidden'); } }); @@ -362,4 +385,17 @@ $visualConsoleItems = VisualConsole::getItemsFromDB( } } }); + + // $(".visual-console-item, .is-editing").bind("click", function(event) { + // console.log('jejejeje'); + // }); + + // $("#visual-console-container, .is-editing").bind("click", function(event) { + // // $(".visual-console-item, .is-editing").unbind("click"); + // // console.log('jijijiji'); + // }); + + $('#button-button_toolbox2').click(function (event){ + visualConsoleManager.visualConsole.deleteItem(); + }); diff --git a/visual_console_client/src/Item.ts b/visual_console_client/src/Item.ts index ba10ff4b5f..d307530fe1 100644 --- a/visual_console_client/src/Item.ts +++ b/visual_console_client/src/Item.ts @@ -66,9 +66,9 @@ export interface ItemClickEvent { } // FIXME: Fix type compatibility. -export interface ItemRemoveEvent { +export interface ItemRemoveEvent { // data: Props; - data: AnyObject; + item: VisualConsoleItem; } export interface ItemMovedEvent { @@ -190,9 +190,7 @@ abstract class VisualConsoleItem { // Event manager for resized events. private readonly resizedEventManager = new TypedEvent(); // Event manager for remove events. - private readonly removeEventManager = new TypedEvent< - ItemRemoveEvent - >(); + private readonly removeEventManager = new TypedEvent(); // List of references to clean the event listeners. private readonly disposables: Disposable[] = []; @@ -746,7 +744,7 @@ abstract class VisualConsoleItem { */ public remove(): void { // Call the remove event. - this.removeEventManager.emit({ data: this.props }); + this.removeEventManager.emit({ item: this }); // Event listeners. this.disposables.forEach(disposable => { try { @@ -974,7 +972,7 @@ abstract class VisualConsoleItem { * To add an event handler to the removal of the item. * @param listener Function which is going to be executed when a item is removed. */ - public onRemove(listener: Listener>): Disposable { + public onRemove(listener: Listener): Disposable { /* * The '.on' function returns a function which will clean the event * listener when executed. We store all the 'dispose' functions to diff --git a/visual_console_client/src/VisualConsole.ts b/visual_console_client/src/VisualConsole.ts index f4561fffff..ce613ca137 100644 --- a/visual_console_client/src/VisualConsole.ts +++ b/visual_console_client/src/VisualConsole.ts @@ -210,6 +210,8 @@ export default class VisualConsole { private readonly movedEventManager = new TypedEvent(); // Event manager for resize events. private readonly resizedEventManager = new TypedEvent(); + // Event manager for remove events. + private readonly removeEventManager = new TypedEvent(); // List of references to clean the event listeners. private readonly disposables: Disposable[] = []; @@ -273,11 +275,12 @@ export default class VisualConsole { * Clear some element references. * @param e Event object. */ - private handleElementRemove: (e: ItemRemoveEvent) => void = e => { + private handleElementRemove: (e: ItemRemoveEvent) => void = e => { // Remove the element from the list and its relations. - this.elementIds = this.elementIds.filter(id => id !== e.data.id); - delete this.elementsById[e.data.id]; - this.clearRelations(e.data.id); + this.elementIds = this.elementIds.filter(id => id !== e.item.props.id); + delete this.elementsById[e.item.props.id]; + this.clearRelations(e.item.props.id); + this.removeEventManager.emit(e); }; // TODO: Document @@ -762,6 +765,22 @@ export default class VisualConsole { return disposable; } + /** + * Add an event handler to the resizement of the visual console elements. + * @param listener Function which is going to be executed when a linked console is moved. + */ + public onItemRemove(listener: Listener): Disposable { + /* + * The '.on' function returns a function which will clean the event + * listener when executed. We store all the 'dispose' functions to + * call them when the item should be cleared. + */ + const disposable = this.removeEventManager.on(listener); + this.disposables.push(disposable); + + return disposable; + } + /** * Enable the edition mode. */ @@ -782,6 +801,17 @@ export default class VisualConsole { this.containerRef.classList.remove("is-editing"); } + /** + * delete item. + */ + public deleteItem(): void { + this.elements.forEach(item => { + if (item.meta.isSelected === true) { + item.remove(); + } + }); + } + /** * Select an item. * @param itemId Item Id.