]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
baculum: Fix #2642 add tool to re-assigning volumes from one pool to another
authorMarcin Haba <marcin.haba@bacula.pl>
Wed, 27 Oct 2021 16:16:29 +0000 (18:16 +0200)
committerEric Bollengier <eric@baculasystems.com>
Thu, 24 Mar 2022 08:03:26 +0000 (09:03 +0100)
After renaming pool Baculum user see warning with instruction what to do to finish the pool rename. User is able to re-assign volumes between pools and at the end remove original pool.

20 files changed:
gui/baculum/protected/Web/Lang/en/messages.mo
gui/baculum/protected/Web/Lang/en/messages.po
gui/baculum/protected/Web/Lang/ja/messages.mo
gui/baculum/protected/Web/Lang/ja/messages.po
gui/baculum/protected/Web/Lang/pl/messages.mo
gui/baculum/protected/Web/Lang/pl/messages.po
gui/baculum/protected/Web/Lang/pt/messages.mo
gui/baculum/protected/Web/Lang/pt/messages.po
gui/baculum/protected/Web/Lang/ru/messages.mo
gui/baculum/protected/Web/Lang/ru/messages.po
gui/baculum/protected/Web/Pages/DirectorView.page
gui/baculum/protected/Web/Pages/DirectorView.php
gui/baculum/protected/Web/Pages/PoolView.page
gui/baculum/protected/Web/Pages/PoolView.php
gui/baculum/protected/Web/Portlets/AssignVolumesToPool.php [new file with mode: 0644]
gui/baculum/protected/Web/Portlets/AssignVolumesToPool.tpl [new file with mode: 0644]
gui/baculum/protected/Web/Portlets/BaculaConfigDirectives.php
gui/baculum/protected/Web/Portlets/BaculaConfigResourceList.php
gui/baculum/protected/Web/Portlets/BaculaConfigResourceList.tpl
gui/baculum/protected/Web/Portlets/LabelVolume.tpl

index f887bf649e6490eba35b9b9b4737d3253805fe2e..be60418d0adfdf369a13301bb2c880be166c2ffe 100644 (file)
Binary files a/gui/baculum/protected/Web/Lang/en/messages.mo and b/gui/baculum/protected/Web/Lang/en/messages.mo differ
index 0d430492ef8e07317a9793246144a9ab45ef0d82..5e55c4c9037ab73d775e397caa393ac39ccb69ec 100644 (file)
@@ -3817,3 +3817,24 @@ msgstr "Please mount volume %volume for storage: %storage, pool: %pool, media ty
 
 msgid "Please create a new volume for storage: %storage, pool: %pool, media type: %mediatype."
 msgstr "Please create a new volume for storage: %storage, pool: %pool, media type: %mediatype."
+
+msgid "Assign volumes from selected pool"
+msgstr "Assign volumes from selected pool"
+
+msgid "This function enables re-assigning volumes from selected pool to this pool."
+msgstr "This function enables re-assigning volumes from selected pool to this pool."
+
+msgid "Please select a pool from which you would like to assign volumes to this pool."
+msgstr "Please select a pool from which you would like to assign volumes to this pool."
+
+msgid "Assigned volume count:"
+msgstr "Assigned volume count:"
+
+msgid "Assign volumes"
+msgstr "Assign volumes"
+
+msgid "No volumes in the pool to assign."
+msgstr "No volumes in the pool to assign."
+
+msgid "The pool has not been renamed but it has been copied with the new name. Please note that if the original pool contained volumes, they have not been moved and they are still assigned to the original pool in the catalog database. To re-assign volumes from the original pool to this one please go to the MAIN MENU &#10148; Pools &#10148; [NEW POOL] &#10148; Tab: Actions and please use the 'Assign volumes' button. After re-assgning volumes you can delete the original pool."
+msgstr "The pool has not been renamed but it has been copied with the new name. Please note that if the original pool contained volumes, they have not been moved and they are still assigned to the original pool in the catalog database. To re-assign volumes from the original pool to this one please go to the MAIN MENU &#10148; Pools &#10148; [NEW POOL] &#10148; Tab: Actions and please use the 'Assign volumes' button. After re-assgning volumes you can delete the original pool."
index fe34e3ece0c2fb9ba6bc9434708c3358e8b47215..4af93a8c7b9cde553b6da82d68bab536a640efd0 100644 (file)
Binary files a/gui/baculum/protected/Web/Lang/ja/messages.mo and b/gui/baculum/protected/Web/Lang/ja/messages.mo differ
index d5df331527cf99a9dedfb81e32a39af6adfaad0a..f240586ea07024e7fdcad916c62cbfc9d68daeff 100644 (file)
@@ -3903,3 +3903,24 @@ msgstr "Please mount volume %volume for storage: %storage, pool: %pool, media ty
 
 msgid "Please create a new volume for storage: %storage, pool: %pool, media type: %mediatype."
 msgstr "Please create a new volume for storage: %storage, pool: %pool, media type: %mediatype."
+
+msgid "Assign volumes from selected pool"
+msgstr "Assign volumes from selected pool"
+
+msgid "This function enables re-assigning volumes from selected pool to this pool."
+msgstr "This function enables re-assigning volumes from selected pool to this pool."
+
+msgid "Please select a pool from which you would like to assign volumes to this pool."
+msgstr "Please select a pool from which you would like to assign volumes to this pool."
+
+msgid "Assigned volume count:"
+msgstr "Assigned volume count:"
+
+msgid "Assign volumes"
+msgstr "Assign volumes"
+
+msgid "No volumes in the pool to assign."
+msgstr "No volumes in the pool to assign."
+
+msgid "The pool has not been renamed but it has been copied with the new name. Please note that if the original pool contained volumes, they have not been moved and they are still assigned to the original pool in the catalog database. To re-assign volumes from the original pool to this one please go to the MAIN MENU &#10148; Pools &#10148; [NEW POOL] &#10148; Tab: Actions and please use the 'Assign volumes' button. After re-assgning volumes you can delete the original pool."
+msgstr "The pool has not been renamed but it has been copied with the new name. Please note that if the original pool contained volumes, they have not been moved and they are still assigned to the original pool in the catalog database. To re-assign volumes from the original pool to this one please go to the MAIN MENU &#10148; Pools &#10148; [NEW POOL] &#10148; Tab: Actions and please use the 'Assign volumes' button. After re-assgning volumes you can delete the original pool."
index 525bd0c107f1604ca009c7c66a9c560d83a8e3ba..c332feb462d61ac6d0d381d3e53ea714948d1176 100644 (file)
Binary files a/gui/baculum/protected/Web/Lang/pl/messages.mo and b/gui/baculum/protected/Web/Lang/pl/messages.mo differ
index 9aac429764c95185c95559282e7fa714ffaa6b7e..0fb140132bba9e34547ecf6e96e0c6f498e45108 100644 (file)
@@ -3828,3 +3828,24 @@ msgstr "Please mount volume %volume for storage: %storage, pool: %pool, media ty
 
 msgid "Please create a new volume for storage: %storage, pool: %pool, media type: %mediatype."
 msgstr "Please create a new volume for storage: %storage, pool: %pool, media type: %mediatype."
+
+msgid "Assign volumes from selected pool"
+msgstr "Assign volumes from selected pool"
+
+msgid "This function enables re-assigning volumes from selected pool to this pool."
+msgstr "This function enables re-assigning volumes from selected pool to this pool."
+
+msgid "Please select a pool from which you would like to assign volumes to this pool."
+msgstr "Please select a pool from which you would like to assign volumes to this pool."
+
+msgid "Assigned volume count:"
+msgstr "Assigned volume count:"
+
+msgid "Assign volumes"
+msgstr "Assign volumes"
+
+msgid "No volumes in the pool to assign."
+msgstr "No volumes in the pool to assign."
+
+msgid "The pool has not been renamed but it has been copied with the new name. Please note that if the original pool contained volumes, they have not been moved and they are still assigned to the original pool in the catalog database. To re-assign volumes from the original pool to this one please go to the MAIN MENU &#10148; Pools &#10148; [NEW POOL] &#10148; Tab: Actions and please use the 'Assign volumes' button. After re-assgning volumes you can delete the original pool."
+msgstr "The pool has not been renamed but it has been copied with the new name. Please note that if the original pool contained volumes, they have not been moved and they are still assigned to the original pool in the catalog database. To re-assign volumes from the original pool to this one please go to the MAIN MENU &#10148; Pools &#10148; [NEW POOL] &#10148; Tab: Actions and please use the 'Assign volumes' button. After re-assgning volumes you can delete the original pool."
index 62d049175e24b1e6ff0214d1c82129069659d80e..6daf4ac577aaa9b3aa408e62dec453b91da362f8 100644 (file)
Binary files a/gui/baculum/protected/Web/Lang/pt/messages.mo and b/gui/baculum/protected/Web/Lang/pt/messages.mo differ
index 30e182d2a5bbef6e8b1985d8b62b50a402bc4ebd..c4bb8f6e0d70069cf6ba3816a749431c27168035 100644 (file)
@@ -3828,3 +3828,24 @@ msgstr "Please mount volume %volume for storage: %storage, pool: %pool, media ty
 
 msgid "Please create a new volume for storage: %storage, pool: %pool, media type: %mediatype."
 msgstr "Please create a new volume for storage: %storage, pool: %pool, media type: %mediatype."
+
+msgid "Assign volumes from selected pool"
+msgstr "Assign volumes from selected pool"
+
+msgid "This function enables re-assigning volumes from selected pool to this pool."
+msgstr "This function enables re-assigning volumes from selected pool to this pool."
+
+msgid "Please select a pool from which you would like to assign volumes to this pool."
+msgstr "Please select a pool from which you would like to assign volumes to this pool."
+
+msgid "Assigned volume count:"
+msgstr "Assigned volume count:"
+
+msgid "Assign volumes"
+msgstr "Assign volumes"
+
+msgid "No volumes in the pool to assign."
+msgstr "No volumes in the pool to assign."
+
+msgid "The pool has not been renamed but it has been copied with the new name. Please note that if the original pool contained volumes, they have not been moved and they are still assigned to the original pool in the catalog database. To re-assign volumes from the original pool to this one please go to the MAIN MENU &#10148; Pools &#10148; [NEW POOL] &#10148; Tab: Actions and please use the 'Assign volumes' button. After re-assgning volumes you can delete the original pool."
+msgstr "The pool has not been renamed but it has been copied with the new name. Please note that if the original pool contained volumes, they have not been moved and they are still assigned to the original pool in the catalog database. To re-assign volumes from the original pool to this one please go to the MAIN MENU &#10148; Pools &#10148; [NEW POOL] &#10148; Tab: Actions and please use the 'Assign volumes' button. After re-assgning volumes you can delete the original pool."
index 929ac449dc3dea697a4e8ec2a3915d29f6c8ace2..cab4255e071da00148e996421fb38616970c6749 100644 (file)
Binary files a/gui/baculum/protected/Web/Lang/ru/messages.mo and b/gui/baculum/protected/Web/Lang/ru/messages.mo differ
index 3e3871312242c2b0e896df8402b995c072703dcf..497ac1409b92882a742a84f1b1a1383b6fa50722 100644 (file)
@@ -3828,3 +3828,24 @@ msgstr "Please mount volume %volume for storage: %storage, pool: %pool, media ty
 
 msgid "Please create a new volume for storage: %storage, pool: %pool, media type: %mediatype."
 msgstr "Please create a new volume for storage: %storage, pool: %pool, media type: %mediatype."
+
+msgid "Assign volumes from selected pool"
+msgstr "Assign volumes from selected pool"
+
+msgid "This function enables re-assigning volumes from selected pool to this pool."
+msgstr "This function enables re-assigning volumes from selected pool to this pool."
+
+msgid "Please select a pool from which you would like to assign volumes to this pool."
+msgstr "Please select a pool from which you would like to assign volumes to this pool."
+
+msgid "Assigned volume count:"
+msgstr "Assigned volume count:"
+
+msgid "Assign volumes"
+msgstr "Assign volumes"
+
+msgid "No volumes in the pool to assign."
+msgstr "No volumes in the pool to assign."
+
+msgid "The pool has not been renamed but it has been copied with the new name. Please note that if the original pool contained volumes, they have not been moved and they are still assigned to the original pool in the catalog database. To re-assign volumes from the original pool to this one please go to the MAIN MENU &#10148; Pools &#10148; [NEW POOL] &#10148; Tab: Actions and please use the 'Assign volumes' button. After re-assgning volumes you can delete the original pool."
+msgstr "The pool has not been renamed but it has been copied with the new name. Please note that if the original pool contained volumes, they have not been moved and they are still assigned to the original pool in the catalog database. To re-assign volumes from the original pool to this one please go to the MAIN MENU &#10148; Pools &#10148; [NEW POOL] &#10148; Tab: Actions and please use the 'Assign volumes' button. After re-assgning volumes you can delete the original pool."
index 00bfad7462a30d2441ef6bb11c573a038da00cd1..f24b68a9f62cbe18b8a61b89db0f86c78d3aee68 100644 (file)
@@ -935,6 +935,10 @@ function load_director_config() {
                <com:TCallback ID="LoadDirectorResourcesConfig" OnCallback="loadDirectorResourcesConfig" />
                <script>
 function load_dir_res_config(resource) {
+       // hide pool warning
+       document.getElementById('director_view_rename_resource').style.display = 'none';
+
+       // do load Director resource request
        var cb = <%=$this->LoadDirectorResourcesConfig->ActiveControl->Javascript%>;
        cb.setCallbackParameter(resource);
        cb.dispatch();
@@ -986,11 +990,16 @@ function load_dir_res_config(resource) {
                                ShowCancelButton="false"
                        />
                </div>
+               <div id="director_view_rename_resource" class="w3-panel w3-pale-yellow w3-border" style="display: none">
+                       <h3><%[ Warning ]%></h3>
+                       <p><%[ The pool has not been renamed but it has been copied with the new name. Please note that if the original pool contained volumes, they have not been moved and they are still assigned to the original pool in the catalog database. To re-assign volumes from the original pool to this one please go to the MAIN MENU &#10148; Pools &#10148; [NEW POOL] &#10148; Tab: Actions and please use the 'Assign volumes' button. After re-assgning volumes you can delete the original pool. ]%></p>
+               </div>
                <div id="director_resources_config_form" class="subtab_item" style="display: none">
                        <com:Application.Web.Portlets.BaculaConfigResourceList
                                ID="DirectorResourcesConfig"
                                ComponentType="dir"
                                ResourceList="<%=[[ 'name' => 'Name', 'label' => 'Name' ]]%>"
+                               OnRename="renameResource"
                        />
                </div>
        </div>
index 614a8bb07d5285ad35cd6a021064070a2a9043fa..0281fd6464fde377ffdd71b8649642572875057a 100644 (file)
@@ -20,6 +20,7 @@
  * Bacula(R) is a registered trademark of Kern Sibbald.
  */
 
+Prado::using('System.Web.UI.TCommandEventParameter');
 Prado::using('System.Web.UI.ActiveControls.TCallback');
 Prado::using('Application.Web.Class.BaculumWebPage');
 
@@ -131,5 +132,14 @@ class DirectorView extends BaculumWebPage {
 
                $this->getCallbackClient()->callClientFunction('init_graphical_director_status', [$client_status]);
        }
+
+       public function renameResource($sender, $param) {
+               if ($param instanceof TCommandEventParameter) {
+                       $res = $param->getCommandParameter();
+                       if ($res['resource_type'] == 'Pool') {
+                               $this->getCallbackClient()->show('director_view_rename_resource');
+                       }
+               }
+       }
 }
 ?>
index 543307849d675081b50419ca75e1b382ac9cc5d9..d31f9d1d51bbbcc1e627f41a049a48158ac4a5e8 100644 (file)
@@ -3,7 +3,7 @@
        <!-- Header -->
        <header class="w3-container">
                <h5>
-                       <b><i class="fa fa-desktop"></i> <%[ Pool details ]%></b>
+                       <b><i class="fa fa-tape"></i> <%[ Pool details ]%></b>
                </h5>
        </header>
        <h3 class="w3-margin-left">[PoolId <%=$this->getPoolId()%>] <%[ Pool: ]%> <%=$this->getPoolName()%></h3>
@@ -27,7 +27,7 @@
                        ClientSide.OnLoading="$('#status_pool_loading').show();"
                        ClientSide.OnSuccess="$('#status_pool_loading').hide();"
                >
-                       <prop:Text><%=Prado::localize('Update pool')%> &nbsp;<i class="fa fa-wrench"></i></prop:Text>
+                       <prop:Text><i class="fa fa-wrench"></i>&nbsp; <%=Prado::localize('Update pool')%></prop:Text>
                </com:TActiveLinkButton>
                <com:TActiveLinkButton
                        ID="UpdateAllVolInPoolBtn"
                        ClientSide.OnLoading="$('#status_pool_loading').show();"
                        ClientSide.OnSuccess="$('#status_pool_loading').hide();"
                >
-                       <prop:Text><%=Prado::localize('Update all vols in pool')%> &nbsp;<i class="fa fa-wrench"></i></prop:Text>
+                       <prop:Text><i class="fa fa-wrench"></i>&nbsp; <%=Prado::localize('Update all vols in pool')%></prop:Text>
                </com:TActiveLinkButton>
+               <com:Application.Web.Portlets.AssignVolumesToPool
+                       PoolId="<%=$this->getPoolId()%>"
+               />
                <i id="status_pool_loading" class="fa fa-sync w3-spin" style="display: none; vertical-align: super;"></i>
                <div class="w3-row">
                        <div class="w3-card w3-quarter w3-padding w3-margin-right details_card">
                </table>
        </div>
        <div class="w3-container tab_item" id="pool_config" style="display: none">
+               <div id="pool_view_rename_resource" class="w3-panel w3-pale-yellow w3-border" style="display: none">
+                       <h3><%[ Warning ]%></h3>
+                       <p><%[ The pool has not been renamed but it has been copied with the new name. Please note that if the original pool contained volumes, they have not been moved and they are still assigned to the original pool in the catalog database. To re-assign volumes from the original pool to this one please go to the MAIN MENU &#10148; Pools &#10148; [NEW POOL] &#10148; Tab: Actions and please use the 'Assign volumes' button. After re-assgning volumes you can delete the original pool. ]%></p>
+               </div>
                <com:Application.Web.Portlets.BaculaConfigDirectives
                        ID="PoolConfig"
                        ComponentType="dir"
                        ResourceType="Pool"
                        ShowCancelButton="false"
+                       OnRename="showAssignVolumesWarning"
                />
        </div>
 <script type="text/javascript">
index 96ecd8791c39433461325fd72ab0ad73df606acd..5c1240a02ae548d77ea30cc09da955d006fa7c12 100644 (file)
@@ -217,5 +217,8 @@ class PoolView extends BaculumWebPage {
                }
        }
 
+       public function showAssignVolumesWarning($sender, $param) {
+               $this->getCallbackClient()->show('pool_view_rename_resource');
+       }
 }
 ?>
diff --git a/gui/baculum/protected/Web/Portlets/AssignVolumesToPool.php b/gui/baculum/protected/Web/Portlets/AssignVolumesToPool.php
new file mode 100644 (file)
index 0000000..56d24fa
--- /dev/null
@@ -0,0 +1,116 @@
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum   - Bacula web interface
+ *
+ * Copyright (C) 2013-2021 Kern Sibbald
+ *
+ * The main author of Baculum is Marcin Haba.
+ * The original author of Bacula is Kern Sibbald, with contributions
+ * from many others, a complete list can be found in the file AUTHORS.
+ *
+ * You may use this file and others of this release according to the
+ * license defined in the LICENSE file, which includes the Affero General
+ * Public License, v3.0 ("AGPLv3") and some additional permissions and
+ * terms pursuant to its AGPLv3 Section 7.
+ *
+ * This notice must be preserved when any source code is
+ * conveyed and/or propagated.
+ *
+ * Bacula(R) is a registered trademark of Kern Sibbald.
+ */
+
+Prado::using('Application.Web.Portlets.Portlets');
+
+/**
+ * Assign volumes to pool control.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category Control
+ * @package Baculum Web
+ */
+class AssignVolumesToPool extends Portlets {
+
+       const POOL_ID = 'PoolId';
+
+       /**
+        * Set pool identifier.
+        *
+        * @return none;
+        */
+       public function setPoolId($pool) {
+               settype($pool, 'integer');
+               $this->setViewState(self::POOL_ID, $pool);
+       }
+
+       /**
+        * Get pool identifier.
+        *
+        * @return integer pool identifier
+        */
+       public function getPoolId() {
+               return $this->getViewState(self::POOL_ID, 0);
+       }
+
+       public function loadValues() {
+               $pools = $this->Application->getModule('api')->get(['pools']);
+               $pool_list = [];
+               if ($pools->error === 0) {
+                       $curr_poolid = $this->getPoolId();
+                       foreach($pools->output as $pool) {
+                               if ($pool->poolid == $curr_poolid) {
+                                       continue;
+                               }
+                               $pool_list[$pool->poolid] = $pool->name;
+                       }
+               }
+               $this->Pool->DataSource = $pool_list;
+               $this->Pool->dataBind();
+       }
+
+       public function loadVolumeList($sender, $param) {
+               $poolid = $this->Pool->SelectedValue;
+               $volumes = $this->getModule('api')->get(
+                       ['pools', $poolid, 'volumes']
+               );
+               if ($volumes->error === 0) {
+                       if (count($volumes->output) > 0) {
+                               $this->getPage()->getCallbackClient()->callClientFunction(
+                                       'oAssignVolumesToPool.load_volume_list_cb',
+                                       [$volumes->output]
+                               );
+                       } else {
+                               $this->AssignVolumesLog->Text .= PHP_EOL . Prado::localize('No volumes in the pool to assign.');
+                               $this->getPage()->getCallbackClient()->show('assign_volumes_log');
+                               $this->getPage()->getCallbackClient()->callClientFunction(
+                                       'oAssignVolumesToPool.show_loader',
+                                       [false]
+                               );
+                       }
+               }
+       }
+
+       public function assignVolume($sender, $param) {
+               $mediaid = $param->getCallbackParameter();
+               if (!is_numeric($mediaid) || $mediaid <= 0) {
+                       return;
+               }
+               $mediaid = intval($mediaid);
+               if ($mediaid === 0) {
+                       return;
+               }
+               $poolid = $this->getPoolId();
+               $result = $this->getModule('api')->set(
+                       ['volumes', $mediaid],
+                       ['poolid' => $poolid]
+               );
+               if ($result->error === 0) {
+                       $this->getPage()->getCallbackClient()->callClientFunction('oAssignVolumesToPool.set_logbox_scroll');
+                       $this->AssignVolumesLog->Text .= PHP_EOL . implode(PHP_EOL, $result->output);
+                       $this->getPage()->getCallbackClient()->show('assign_volumes_log');
+                       // try to assign next volume
+                       $this->getPage()->getCallbackClient()->callClientFunction('oAssignVolumesToPool.assign_volume');
+               }
+       }
+}
+?>
diff --git a/gui/baculum/protected/Web/Portlets/AssignVolumesToPool.tpl b/gui/baculum/protected/Web/Portlets/AssignVolumesToPool.tpl
new file mode 100644 (file)
index 0000000..34907b0
--- /dev/null
@@ -0,0 +1,155 @@
+<com:TActiveLinkButton
+       CssClass="w3-button w3-green w3-margin-bottom"
+       OnClick="loadValues"
+>
+       <prop:Attributes.onclick>
+               oAssignVolumesToPool.show_window(true);
+       </prop:Attributes.onclick>
+       <i class="fa fa-pen-alt"></i> &nbsp;<%[ Assign volumes ]%>
+</com:TActiveLinkButton>
+<div id="assign_volumes_modal" class="w3-modal">
+       <div class="w3-modal-content w3-animate-top w3-card-4">
+               <header class="w3-container w3-teal">
+                       <span onclick="oAssignVolumesToPool.show_window(false);" class="w3-button w3-display-topright">&times;</span>
+                       <h2><%[ Assign volumes from selected pool ]%></h2>
+               </header>
+               <div class="w3-padding">
+                       <p><%[ This function enables re-assigning volumes from selected pool to this pool. ]%></p>
+                       <p><%[ Please select a pool from which you would like to assign volumes to this pool. ]%></p>
+                       <div class="w3-row-padding w3-section">
+                               <div class="w3-col w3-half"><com:TLabel ForControl="Pool" Text="<%[ Pool: ]%>" /></div>
+                               <div class="w3-col w3-half">
+                                       <com:TActiveDropDownList ID="Pool" CssClass="w3-input w3-border" />
+                                       <com:TRequiredFieldValidator
+                                               ValidationGroup="AssignVolumesGroup"
+                                               ControlToValidate="Pool"
+                                               ErrorMessage="<%[ Field required. ]%>"
+                                               Display="Dynamic"
+                                       />
+                               </div>
+                       </div>
+                       <div class="w3-row-padding w3-section">
+                               <div class="w3-col w3-half"><com:TLabel ForControl="Pool" Text="<%[ Assigned volume count: ]%>" /></div>
+                               <div class="w3-col w3-half"><strong id="assign_volumes_counter"></strong>/<strong id="assign_volumes_all"></strong></div>
+                       </div>
+                       <div class="w3-container w3-center w3-section">
+                               <button type="button" class="w3-button w3-red" onclick="oAssignVolumesToPool.show_window(false);"><i class="fa fa-times"></i> &nbsp;<%[ Close ]%></button>
+                               <com:TLinkButton
+                                       ID="AssignVolumesButton"
+                                       CausesValidation="true"
+                                       ValidationGroup="AssignVolumesGroup"
+                                       CssClass="w3-button w3-green"
+                                       Attributes.onclick="oAssignVolumesToPool.load_volume_list(); return false;"
+                               >
+                                       <i class="fa fa-pen-alt"></i> &nbsp;<%[ Assign volumes ]%>
+                               </com:TLinkButton>
+                               &nbsp; <i id="assign_volumes_loading" class="fa fa-sync w3-spin" style="visibility: hidden;"></i>
+                       </div>
+                       <div id="assign_volumes_log" class="w3-panel w3-card w3-light-grey" style="display: none; max-height: 200px; overflow-x: auto;">
+                               <div class="w3-code notranslate">
+                                       <pre><com:TActiveLabel ID="AssignVolumesLog" /></pre>
+                               </div>
+                       </div>
+               </div>
+       </div>
+</div>
+<com:TCallback ID="LoadVolumeList" OnCallback="loadVolumeList" />
+<com:TCallback ID="AssignVolume" OnCallback="assignVolume" />
+<script>
+var oAssignVolumesToPool = {
+       volumes: [],
+       logbox_scroll: false,
+       ids: {
+               modal: 'assign_volumes_modal',
+               loader: 'assign_volumes_loading',
+               logbox: 'assign_volumes_log',
+               counter: 'assign_volumes_counter',
+               all: 'assign_volumes_all'
+       },
+       show_window: function(show) {
+               // clean up previous logs (if any)
+               this.cleanup_joblog();
+
+               // clear counter
+               this.clear_counter();
+
+               var win = document.getElementById(this.ids.modal);
+               win.style.display = show ? 'block' : 'none';
+       },
+       load_volume_list: function() {
+               oAssignVolumesToPool.show_loader(true);
+               oAssignVolumesToPool.clear_counter();
+
+               var cb = <%=$this->LoadVolumeList->ActiveControl->Javascript%>;
+               cb.dispatch();
+       },
+       load_volume_list_cb: function(volumes) {
+               for (var i = 0; i < volumes.length; i++) {
+                       oAssignVolumesToPool.volumes.push(volumes[i].mediaid);
+               }
+               if (oAssignVolumesToPool.volumes.length > 0) {
+                       // prepare log box
+                       oAssignVolumesToPool.prepare_logbox();
+
+                       // start assigning
+                       oAssignVolumesToPool.assign_volume();
+               } else {
+                       oAssignVolumesToPool.show_loader(false);
+               }
+       },
+       assign_volume: function() {
+               oAssignVolumesToPool.prepare_logbox();
+               oAssignVolumesToPool.set_counter();
+               if (oAssignVolumesToPool.volumes.length > 0) {
+                       var cb = <%=$this->AssignVolume->ActiveControl->Javascript%>;
+                       cb.setCallbackParameter(oAssignVolumesToPool.volumes.shift());
+                       cb.dispatch();
+               } else {
+                       oAssignVolumesToPool.show_loader(false);
+               }
+       },
+       show_loader: function(show) {
+               var loader = document.getElementById(oAssignVolumesToPool.ids.loader);
+               loader.style.visibility = show ? 'visible' : 'hidden';
+       },
+       prepare_logbox: function() {
+               var logbox = document.getElementById(this.ids.logbox);
+               logbox.style.display = '';
+               if (this.logbox_scroll) {
+                       logbox.scrollTo(0, logbox.scrollHeight);
+               }
+       },
+       is_logbox_scroll_end: function() {
+               var logbox = document.getElementById(this.ids.logbox);
+               var pos = logbox.scrollHeight - logbox.clientHeight - logbox.scrollTop;
+               return (pos < 2);
+       },
+       set_logbox_scroll: function() {
+               oAssignVolumesToPool.logbox_scroll = oAssignVolumesToPool.is_logbox_scroll_end();
+       },
+       cleanup_joblog: function() {
+               var logbox = document.getElementById(this.ids.logbox);
+               logbox.style.display = 'none';
+               var logbox_content = document.getElementById('<%=$this->AssignVolumesLog->ClientID%>');
+               logbox_content.textContent = '';
+       },
+       set_counter: function() {
+               var counter = document.getElementById(this.ids.counter);
+               var cnt = parseInt(counter.textContent, 10);
+               var all = document.getElementById(this.ids.all);
+               var cnta = parseInt(all.textContent, 10);
+               if (cnt < cnta) {
+                       counter.textContent = ++cnt;
+               }
+               if (all.textContent == 0) {
+                       all.textContent = this.volumes.length;
+               }
+       },
+       clear_counter: function() {
+               var counter = document.getElementById(this.ids.counter);
+               counter.textContent = 0;
+               var all = document.getElementById(this.ids.all);
+               all.textContent = 0;
+       }
+};
+</script>
index 7145a953ae2325f2106116cf996771f4a3a3fcef..1892ef70390463653113a1c88e50c1387eec09a2 100644 (file)
@@ -20,6 +20,7 @@
  * Bacula(R) is a registered trademark of Kern Sibbald.
  */
 
+Prado::using('System.Web.UI.TCommandEventParameter');
 Prado::using('System.Web.UI.ActiveControls.TActiveLabel');
 Prado::using('System.Web.UI.ActiveControls.TActiveLinkButton');
 Prado::using('System.Web.UI.ActiveControls.TActivePanel');
@@ -370,6 +371,11 @@ class BaculaConfigDirectives extends DirectiveListTemplate {
                                        // set new resource name
                                        $this->setResourceName($res_name_dir);
                                        $resource_name = $res_name_dir;
+                                       $param = new TCommandEventParameter('rename', [
+                                               'resource_type' => $resource_type,
+                                               'resource_name' => $resource_name
+                                       ]);
+                                       $this->onRename($param);
                                }
                        }
                } else {
@@ -579,6 +585,16 @@ class BaculaConfigDirectives extends DirectiveListTemplate {
                $host = null;
                $resource_type = $this->getResourceType();
                $resource_name = $this->getResourceName();
+
+               if ($resource_type == 'Pool') {
+                       /**
+                        * For Pools there is done copy resource, not rename, to allow users
+                        * re-assigning volumes from original pool to new pool and at the end
+                        * to remove original pool.
+                        */
+                       return true;
+               }
+
                $config = $this->getConfigData($host, array($component_type));
                $deps = $this->getModule('data_deps')->checkDependencies(
                        $component_type,
@@ -681,7 +697,7 @@ class BaculaConfigDirectives extends DirectiveListTemplate {
        /**
         * Set if buttons should be flexible and available at the bottom of the page.
         *
-        * @return none;
+        * @return none
         */
        public function setShowBottomButtons($show) {
                $show = TPropertyValue::ensureBoolean($show);
@@ -697,10 +713,25 @@ class BaculaConfigDirectives extends DirectiveListTemplate {
                return $this->getViewState(self::SHOW_BOTTOM_BUTTONS, true);
        }
 
+       /**
+        * On save event fired when resource is saved.
+        *
+        * @return none
+        */
        public function onSave($param) {
                $this->raiseEvent('OnSave', $this, $param);
        }
 
+       /**
+        * On rename event fired when resource is renamed.
+        *
+        * @return none
+        */
+       public function onRename($param) {
+               $this->raiseEvent('OnRename', $this, $param);
+       }
+
+
        /**
         * Set if name field should be disabled.
         *
index 1728223d2f98d5f767d65331a06dd0da85e02904..9ed5cf58e0367282e43b5eca1ea43eb080ce0dd3 100644 (file)
@@ -189,6 +189,14 @@ class BaculaConfigResourceList extends Portlets {
                $this->getPage()->getCallbackClient()->show($err_win_id);
        }
 
+       public function renameResource($sender, $param) {
+               $this->onRename($param);
+       }
+
+       public function onRename($param) {
+               $this->raiseEvent('OnRename', $this, $param);
+       }
+
        public function getHost() {
                return $this->getViewState(self::HOST);
        }
index 88bf0967d8ef50687efb462015e6b6c1e485b29e..141ee582987d3bcf4a5d46105c43e83838236661 100644 (file)
@@ -141,6 +141,7 @@ var oBaculaConfigResourceList<%=$this->ClientID%> = {
                                ShowBottomButtons="false"
                                SaveDirectiveActionOk="oBaculaConfigResourceWindow<%=$this->ClientID%>.close_resource_window();"
                                OnSave="loadResourceListTable"
+                               OnRename="renameResource"
                        />
                </div>
        </div>
index 6da2e6cfa83c835da72c4d1e79eee203c486d139..af98a72939cfc19c9bf0f83d02f9e9945d026c4a 100644 (file)
@@ -8,7 +8,6 @@
        </prop:Attributes.onclick>
        <i class="fa fa-tag"></i> &nbsp;<%[ Label volume(s) ]%>
 </com:TActiveLinkButton>
-</button>
 <div id="label_volume" class="w3-modal">
        <div class="w3-modal-content w3-animate-top w3-card-4">
                <header class="w3-container w3-teal">