From 2030c0beee42477423c34d2c8fa17b51413737be Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Wed, 31 Jul 2019 13:23:25 +0200 Subject: [PATCH] added copy an item --- .../javascript/pandora_visual_console.js | 121 +++++++++++++++++- pandora_console/include/rest-api/index.php | 25 ++++ .../models/VisualConsole/Container.php | 22 ---- .../rest-api/models/VisualConsole/Item.php | 20 +-- .../models/VisualConsole/Items/Line.php | 20 +++ .../operation/visual_console/view.php | 7 +- visual_console_client/src/VisualConsole.ts | 4 +- 7 files changed, 183 insertions(+), 36 deletions(-) diff --git a/pandora_console/include/javascript/pandora_visual_console.js b/pandora_console/include/javascript/pandora_visual_console.js index df6fadc01f..823264f065 100755 --- a/pandora_console/include/javascript/pandora_visual_console.js +++ b/pandora_console/include/javascript/pandora_visual_console.js @@ -470,7 +470,6 @@ function createVisualConsole( var taskId = "visual-console-item-update-" + id; - // Persist the new position. asyncTaskManager .add(taskId, function(done) { var abortable = removeVisualConsoleItem( @@ -489,7 +488,8 @@ function createVisualConsole( // Add the item to the list. var itemRetrieved = aux.props; itemRetrieved["receivedAt"] = new Date(); - visualConsole.addElement(itemRetrieved); + var newItem = visualConsole.addElement(itemRetrieved); + newItem.setMeta({ editMode: true }); } done(); @@ -503,6 +503,57 @@ function createVisualConsole( }; }) .init(); + }, + copyItem: function(item) { + var id = item.props.id; + item.setMeta({ isUpdating: true }); + + var taskId = "visual-console-item-update-" + id; + + // Persist the new position. + asyncTaskManager + .add(taskId, function(done) { + var abortable = copyVisualConsoleItem( + baseUrl, + visualConsole.props.id, + id, + function(error, data) { + if (error || !data) { + console.log( + "[ERROR]", + "[VISUAL-CONSOLE-CLIENT]", + "[API]", + error ? error.message : "Invalid response" + ); + + item.setMeta({ isUpdating: false }); + + done(); + return; // Stop task execution. + } + + item.setMeta({ isUpdating: false }); + + var itemRetrieved = item.props; + itemRetrieved["x"] = itemRetrieved["x"] + 20; + itemRetrieved["y"] = itemRetrieved["y"] + 20; + itemRetrieved["receivedAt"] = new Date(); + itemRetrieved["id"] = data; + + var newItem = visualConsole.addElement(itemRetrieved); + newItem.setMeta({ editMode: true }); + + done(); + } + ); + + return { + cancel: function() { + abortable.abort(); + } + }; + }) + .init(); } }; } @@ -812,6 +863,7 @@ function removeVisualConsoleItem(baseUrl, vcId, vcItemId, callback) { /** * Fetch groups access user. * @param {string} baseUrl Base URL to build the API path. + * @param {number} vcId Identifier of the Visual Console. * @param {function} callback Function to be executed on request success or fail. * @return {Object} Cancellable. Object which include and .abort([statusText]) function. */ @@ -871,6 +923,71 @@ function getGroupsVisualConsoleItem(baseUrl, vcId, callback) { }; } +/** + * Copy an item. + * @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 copyVisualConsoleItem(baseUrl, vcId, vcItemId, callback) { + 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 + .post( + apiPath, + { + page: "include/rest-api/index", + copyVisualConsoleItem: 1, + visualConsoleId: vcId, + visualConsoleItemId: vcItemId + }, + "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 1eaa66c2c9..a234cbe576 100644 --- a/pandora_console/include/rest-api/index.php +++ b/pandora_console/include/rest-api/index.php @@ -17,6 +17,7 @@ $getVisualConsoleItems = (bool) get_parameter('getVisualConsoleItems'); $updateVisualConsoleItem = (bool) get_parameter('updateVisualConsoleItem'); $getVisualConsoleItem = (bool) get_parameter('getVisualConsoleItem'); $removeVisualConsoleItem = (bool) get_parameter('removeVisualConsoleItem'); +$copyVisualConsoleItem = (bool) get_parameter('copyVisualConsoleItem'); $getGroupsVisualConsoleItem = (bool) get_parameter('getGroupsVisualConsoleItem'); ob_clean(); @@ -107,6 +108,7 @@ if ($getVisualConsole === true) { return; } else if ($updateVisualConsoleItem === true) { $data = get_parameter('data'); + $data['id'] = $itemId; $result = $item->save($data); echo $item; @@ -141,6 +143,29 @@ if ($getVisualConsole === true) { $data = get_parameter('data'); $result = $item::delete($itemId); + echo $result; + return; +} else if ($copyVisualConsoleItem === true) { + $itemId = (int) get_parameter('visualConsoleItemId'); + + // Get a copy of the item. + $item = VisualConsole::getItemFromDB($itemId); + $data = $item->toArray(); + $data['id_layout'] = $visualConsoleId; + $data['x'] = ($data['x'] + 20); + $data['y'] = ($data['y'] + 20); + unset($data['id']); + + $class = VisualConsole::getItemClass((int) $data['type']); + try { + // Save the new item. + $result = $class::save($data); + } catch (\Throwable $th) { + // There is no item in the database. + echo false; + return; + } + echo $result; return; } else if ($getGroupsVisualConsoleItem === true) { diff --git a/pandora_console/include/rest-api/models/VisualConsole/Container.php b/pandora_console/include/rest-api/models/VisualConsole/Container.php index 827c9ce43b..6ae852d9e8 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Container.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Container.php @@ -440,28 +440,6 @@ final class Container extends Model 'id_layout', ]; - // Override the filter if the groups filter is not empty. - if (count($groupsFilter) > 0) { - // Filter group for elements groups. - $filter = []; - $filter[] = \db_format_array_where_clause_sql( - [ - 'id' => $itemId, - 'element_group' => $groupsFilter, - ] - ); - - // Filter groups for type groups. - // Only true condition if type is GROUP_ITEM. - $filter[] = '('.\db_format_array_where_clause_sql( - [ - 'id' => $itemId, - 'type' => GROUP_ITEM, - 'id_group' => $groupsFilter, - ] - ).')'; - } - $row = \db_get_row_filter( 'tlayout_data', $filter, diff --git a/pandora_console/include/rest-api/models/VisualConsole/Item.php b/pandora_console/include/rest-api/models/VisualConsole/Item.php index dab6d38619..2d3e42213a 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Item.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Item.php @@ -1635,22 +1635,24 @@ class Item extends CachedModel * * @overrides Model::save. */ - public function save(array $data=[]): bool + public function save(array $data=[]): int { - $dataModelEncode = $this->encode($this->toArray()); - $dataEncode = $this->encode($data); - - $save = array_merge($dataModelEncode, $dataEncode); - - if (!empty($save)) { - if (empty($save['id'])) { + if (!empty($data)) { + if (empty($data['id'])) { // Insert. + $save = static::encode($data); $result = \db_process_sql_insert('tlayout_data', $save); if ($result) { $item = static::fromDB(['id' => $result]); + $item->setData($item->toArray()); } } else { // Update. + $dataModelEncode = $this->encode($this->toArray()); + $dataEncode = $this->encode($data); + + $save = array_merge($dataModelEncode, $dataEncode); + $result = \db_process_sql_update('tlayout_data', $save, ['id' => $save['id']]); // Invalidate the item's cache. if ($result !== false && $result > 0) { @@ -1671,7 +1673,7 @@ class Item extends CachedModel } } - return (bool) $result; + return $result; } diff --git a/pandora_console/include/rest-api/models/VisualConsole/Items/Line.php b/pandora_console/include/rest-api/models/VisualConsole/Items/Line.php index 4b177c30b2..e7f4e7dc67 100644 --- a/pandora_console/include/rest-api/models/VisualConsole/Items/Line.php +++ b/pandora_console/include/rest-api/models/VisualConsole/Items/Line.php @@ -405,4 +405,24 @@ final class Line extends Model } + /** + * Delete a line 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] + ); + + return (bool) $result; + } + + } diff --git a/pandora_console/operation/visual_console/view.php b/pandora_console/operation/visual_console/view.php index b2d61aae61..6861122755 100644 --- a/pandora_console/operation/visual_console/view.php +++ b/pandora_console/operation/visual_console/view.php @@ -397,7 +397,6 @@ $visualConsoleItems = VisualConsole::getItemsFromDB( }); $('#button-button_delete').click(function (event){ - // visualConsoleManager.visualConsole.deleteItem(); visualConsoleManager.visualConsole.elements.forEach(item => { if (item.meta.isSelected === true) { visualConsoleManager.deleteItem(item); @@ -406,6 +405,10 @@ $visualConsoleItems = VisualConsole::getItemsFromDB( }); $('#button-button_copy').click(function (event){ - + visualConsoleManager.visualConsole.elements.forEach(item => { + if (item.meta.isSelected === true) { + visualConsoleManager.copyItem(item); + } + }); }); diff --git a/visual_console_client/src/VisualConsole.ts b/visual_console_client/src/VisualConsole.ts index c50582d1e1..f4f734c7bf 100644 --- a/visual_console_client/src/VisualConsole.ts +++ b/visual_console_client/src/VisualConsole.ts @@ -359,7 +359,7 @@ export default class VisualConsole { * To create a new element add it to the DOM. * @param item. Raw representation of the item's data. */ - public addElement(item: AnyObject, context: this = this): void { + public addElement(item: AnyObject, context: this = this) { try { const itemInstance = itemInstanceFrom(item); // Add the item to the list. @@ -375,9 +375,11 @@ export default class VisualConsole { // Add the item to the DOM. context.containerRef.append(itemInstance.elementRef); + return itemInstance; } catch (error) { console.log("Error creating a new element:", error.message); } + return; } /**