]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
baculum: New migrate job wizard
authorMarcin Haba <marcin.haba@bacula.pl>
Thu, 21 Oct 2021 05:23:20 +0000 (07:23 +0200)
committerMarcin Haba <marcin.haba@bacula.pl>
Thu, 21 Oct 2021 05:25:35 +0000 (07:25 +0200)
15 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/JobHistoryList.page
gui/baculum/protected/Web/Pages/JobList.page
gui/baculum/protected/Web/Pages/NewMigrateJobWizard.page [new file with mode: 0644]
gui/baculum/protected/Web/Pages/NewMigrateJobWizard.php [new file with mode: 0644]
gui/baculum/protected/Web/endpoints.xml

index 1e4002bf885605bc076ef4de20780338b8247f25..b9b82fc4a8a8a5bb4f4fc064da24a0866869bb42 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 11109dfbc6f9a0809054f3504cc4fde59fb488d9..7f2dee29ec2f535a85705cbf772ebaa8086cb839 100644 (file)
@@ -3730,3 +3730,78 @@ msgstr "Setup your custom schedule"
 
 msgid "Override directives"
 msgstr "Override directives"
+
+msgid "Migrate by job"
+msgstr "Migrate by job"
+
+msgid "Migrate by client"
+msgstr "Migrate by client"
+
+msgid "Migrate by volume"
+msgstr "Migrate by volume"
+
+msgid "Migrate by smallest volume"
+msgstr "Migrate by smallest volume"
+
+msgid "Migrate by oldest volume"
+msgstr "Migrate by oldest volume"
+
+msgid "Migrate using Pool occupancy"
+msgstr "Migrate using Pool occupancy"
+
+msgid "Migrate by Pool time"
+msgstr "Migrate by Pool time"
+
+msgid "Migrate by SQL query"
+msgstr "Migrate by SQL query"
+
+msgid "New migrate job wizard"
+msgstr "New migrate job wizard"
+
+msgid "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing i     t to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+msgstr "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing i     t to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+
+msgid "Step 2 - what you want to migrate"
+msgstr "Step 2 - what you want to migrate"
+
+msgid "Please select a pool from which you want to migrate data."
+msgstr "Please select a pool from which you want to migrate data."
+
+msgid "The source pool will be examined for finding backup jobs to migrate."
+msgstr "The source pool will be examined for finding backup jobs to migrate."
+
+msgid "Please select a storage using which you want to read migrate data."
+msgstr "Please select a storage using which you want to read migrate data."
+
+msgid "Because you selected migrate using Pool occupancy, to chosen source pool %pool will be added two directives: Migration Low Bytes and Migration High Bytes."
+msgstr "Because you selected migrate using Pool occupancy, to chosen source pool %pool will be added two directives: Migration Low Bytes and Migration High Bytes."
+
+msgid "Because you selected migrate using Pool time, to chosen source pool %pool will be added the Migration Time directive."
+msgstr "Because you selected migrate using Pool time, to chosen source pool %pool will be added the Migration Time directive."
+
+msgid "Step 3 - how would you like to migrate"
+msgstr "Step 3 - how would you like to migrate"
+
+msgid "Step 4 - where you like to migrate"
+msgstr "Step 4 - where you like to migrate"
+
+msgid "Please select a storage using which you want to write migrated data."
+msgstr "Please select a storage using which you want to write migrated data."
+
+msgid "Step 5 - migrate job options"
+msgstr "Step 5 - migrate job options"
+
+msgid "Purge jobs"
+msgstr "Purge jobs"
+
+msgid "Level, Client and FileSet are not used during migrate jobs running but they are required to define in migrate job resource as the standard Job directives."
+msgstr "Level, Client and FileSet are not used during migrate jobs running but they are required to define in migrate job resource as the standard Job directives."
+
+msgid "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+msgstr "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+
+msgid "New migrate job"
+msgstr "New migrate job"
+
+msgid "Please select the criteria that will be used for selecting backup jobs to migrate."
+msgstr "Please select the criteria that will be used for selecting backup jobs to migrate."
index 0894da3bafe0fc9ccfb243ff05bf16911efaa0e5..5193c2fff903678956b03d2de913e5493292a3b2 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 eb7b7e012e4a26dbf5ce8d16af0c6220915b17ae..c4e51893547e2511beff799573cd1d0114bfc4ea 100644 (file)
@@ -3816,3 +3816,78 @@ msgstr "Setup your custom schedule"
 
 msgid "Override directives"
 msgstr "Override directives"
+
+msgid "Migrate by job"
+msgstr "Migrate by job"
+
+msgid "Migrate by client"
+msgstr "Migrate by client"
+
+msgid "Migrate by volume"
+msgstr "Migrate by volume"
+
+msgid "Migrate by smallest volume"
+msgstr "Migrate by smallest volume"
+
+msgid "Migrate by oldest volume"
+msgstr "Migrate by oldest volume"
+
+msgid "Migrate using Pool occupancy"
+msgstr "Migrate using Pool occupancy"
+
+msgid "Migrate by Pool time"
+msgstr "Migrate by Pool time"
+
+msgid "Migrate by SQL query"
+msgstr "Migrate by SQL query"
+
+msgid "New migrate job wizard"
+msgstr "New migrate job wizard"
+
+msgid "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing i     t to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+msgstr "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing i     t to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+
+msgid "Step 2 - what you want to migrate"
+msgstr "Step 2 - what you want to migrate"
+
+msgid "Please select a pool from which you want to migrate data."
+msgstr "Please select a pool from which you want to migrate data."
+
+msgid "The source pool will be examined for finding backup jobs to migrate."
+msgstr "The source pool will be examined for finding backup jobs to migrate."
+
+msgid "Please select a storage using which you want to read migrate data."
+msgstr "Please select a storage using which you want to read migrate data."
+
+msgid "Because you selected migrate using Pool occupancy, to chosen source pool %pool will be added two directives: Migration Low Bytes and Migration High Bytes."
+msgstr "Because you selected migrate using Pool occupancy, to chosen source pool %pool will be added two directives: Migration Low Bytes and Migration High Bytes."
+
+msgid "Because you selected migrate using Pool time, to chosen source pool %pool will be added the Migration Time directive."
+msgstr "Because you selected migrate using Pool time, to chosen source pool %pool will be added the Migration Time directive."
+
+msgid "Step 3 - how would you like to migrate"
+msgstr "Step 3 - how would you like to migrate"
+
+msgid "Step 4 - where you like to migrate"
+msgstr "Step 4 - where you like to migrate"
+
+msgid "Please select a storage using which you want to write migrated data."
+msgstr "Please select a storage using which you want to write migrated data."
+
+msgid "Step 5 - migrate job options"
+msgstr "Step 5 - migrate job options"
+
+msgid "Purge jobs"
+msgstr "Purge jobs"
+
+msgid "Level, Client and FileSet are not used during migrate jobs running but they are required to define in migrate job resource as the standard Job directives."
+msgstr "Level, Client and FileSet are not used during migrate jobs running but they are required to define in migrate job resource as the standard Job directives."
+
+msgid "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+msgstr "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+
+msgid "New migrate job"
+msgstr "New migrate job"
+
+msgid "Please select the criteria that will be used for selecting backup jobs to migrate."
+msgstr "Please select the criteria that will be used for selecting backup jobs to migrate."
index 20a1f08925f59a6c0e4778fa5199dcc7e5043199..6f143272673837ce8aee0b6f6ccc4524f8a96ca3 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 468d6ea4aaf7e38fd97bd812372385def3a41a3a..769f6117808ca820f5b71618d200323e06782f10 100644 (file)
@@ -3741,3 +3741,78 @@ msgstr "Ustaw swój własny harmonogram"
 msgid "Override directives"
 msgstr "Zastąp dyrektywy"
 
+
+msgid "Migrate by job"
+msgstr "Migrate by job"
+
+msgid "Migrate by client"
+msgstr "Migrate by client"
+
+msgid "Migrate by volume"
+msgstr "Migrate by volume"
+
+msgid "Migrate by smallest volume"
+msgstr "Migrate by smallest volume"
+
+msgid "Migrate by oldest volume"
+msgstr "Migrate by oldest volume"
+
+msgid "Migrate using Pool occupancy"
+msgstr "Migrate using Pool occupancy"
+
+msgid "Migrate by Pool time"
+msgstr "Migrate by Pool time"
+
+msgid "Migrate by SQL query"
+msgstr "Migrate by SQL query"
+
+msgid "New migrate job wizard"
+msgstr "New migrate job wizard"
+
+msgid "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing i     t to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+msgstr "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing i     t to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+
+msgid "Step 2 - what you want to migrate"
+msgstr "Step 2 - what you want to migrate"
+
+msgid "Please select a pool from which you want to migrate data."
+msgstr "Please select a pool from which you want to migrate data."
+
+msgid "The source pool will be examined for finding backup jobs to migrate."
+msgstr "The source pool will be examined for finding backup jobs to migrate."
+
+msgid "Please select a storage using which you want to read migrate data."
+msgstr "Please select a storage using which you want to read migrate data."
+
+msgid "Because you selected migrate using Pool occupancy, to chosen source pool %pool will be added two directives: Migration Low Bytes and Migration High Bytes."
+msgstr "Because you selected migrate using Pool occupancy, to chosen source pool %pool will be added two directives: Migration Low Bytes and Migration High Bytes."
+
+msgid "Because you selected migrate using Pool time, to chosen source pool %pool will be added the Migration Time directive."
+msgstr "Because you selected migrate using Pool time, to chosen source pool %pool will be added the Migration Time directive."
+
+msgid "Step 3 - how would you like to migrate"
+msgstr "Step 3 - how would you like to migrate"
+
+msgid "Step 4 - where you like to migrate"
+msgstr "Step 4 - where you like to migrate"
+
+msgid "Please select a storage using which you want to write migrated data."
+msgstr "Please select a storage using which you want to write migrated data."
+
+msgid "Step 5 - migrate job options"
+msgstr "Step 5 - migrate job options"
+
+msgid "Purge jobs"
+msgstr "Purge jobs"
+
+msgid "Level, Client and FileSet are not used during migrate jobs running but they are required to define in migrate job resource as the standard Job directives."
+msgstr "Level, Client and FileSet are not used during migrate jobs running but they are required to define in migrate job resource as the standard Job directives."
+
+msgid "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+msgstr "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+
+msgid "New migrate job"
+msgstr "New migrate job"
+
+msgid "Please select the criteria that will be used for selecting backup jobs to migrate."
+msgstr "Please select the criteria that will be used for selecting backup jobs to migrate."
index 327bdc0c6519d101ba12bd571c88458c1e62e81f..17fa3db624ffbd165958e79b12b2550517861357 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 1b6e8de7429bb8e2c817234bd27e246667ccd37c..551b9744b34400cb2bf76cdcec96123dc10ecfce 100644 (file)
@@ -3741,3 +3741,78 @@ msgstr "Configurar seu agendamento personalizado"
 msgid "Override directives"
 msgstr "Substituir diretivas"
 
+
+msgid "Migrate by job"
+msgstr "Migrate by job"
+
+msgid "Migrate by client"
+msgstr "Migrate by client"
+
+msgid "Migrate by volume"
+msgstr "Migrate by volume"
+
+msgid "Migrate by smallest volume"
+msgstr "Migrate by smallest volume"
+
+msgid "Migrate by oldest volume"
+msgstr "Migrate by oldest volume"
+
+msgid "Migrate using Pool occupancy"
+msgstr "Migrate using Pool occupancy"
+
+msgid "Migrate by Pool time"
+msgstr "Migrate by Pool time"
+
+msgid "Migrate by SQL query"
+msgstr "Migrate by SQL query"
+
+msgid "New migrate job wizard"
+msgstr "New migrate job wizard"
+
+msgid "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing i     t to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+msgstr "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing i     t to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+
+msgid "Step 2 - what you want to migrate"
+msgstr "Step 2 - what you want to migrate"
+
+msgid "Please select a pool from which you want to migrate data."
+msgstr "Please select a pool from which you want to migrate data."
+
+msgid "The source pool will be examined for finding backup jobs to migrate."
+msgstr "The source pool will be examined for finding backup jobs to migrate."
+
+msgid "Please select a storage using which you want to read migrate data."
+msgstr "Please select a storage using which you want to read migrate data."
+
+msgid "Because you selected migrate using Pool occupancy, to chosen source pool %pool will be added two directives: Migration Low Bytes and Migration High Bytes."
+msgstr "Because you selected migrate using Pool occupancy, to chosen source pool %pool will be added two directives: Migration Low Bytes and Migration High Bytes."
+
+msgid "Because you selected migrate using Pool time, to chosen source pool %pool will be added the Migration Time directive."
+msgstr "Because you selected migrate using Pool time, to chosen source pool %pool will be added the Migration Time directive."
+
+msgid "Step 3 - how would you like to migrate"
+msgstr "Step 3 - how would you like to migrate"
+
+msgid "Step 4 - where you like to migrate"
+msgstr "Step 4 - where you like to migrate"
+
+msgid "Please select a storage using which you want to write migrated data."
+msgstr "Please select a storage using which you want to write migrated data."
+
+msgid "Step 5 - migrate job options"
+msgstr "Step 5 - migrate job options"
+
+msgid "Purge jobs"
+msgstr "Purge jobs"
+
+msgid "Level, Client and FileSet are not used during migrate jobs running but they are required to define in migrate job resource as the standard Job directives."
+msgstr "Level, Client and FileSet are not used during migrate jobs running but they are required to define in migrate job resource as the standard Job directives."
+
+msgid "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+msgstr "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+
+msgid "New migrate job"
+msgstr "New migrate job"
+
+msgid "Please select the criteria that will be used for selecting backup jobs to migrate."
+msgstr "Please select the criteria that will be used for selecting backup jobs to migrate."
index 2d8191b76b9aa944bea547384cdf300106df9294..4fc1dfd01ac3e37e335d8f5854525d7044316c93 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 23fdb1eee1b1681d2fe5704181cc463f9bdaa7d9..1f2997886198a06ca4aa6dc89775fdb7043c4bb6 100644 (file)
@@ -3741,3 +3741,78 @@ msgstr "Настройте свой индивидуальный график"
 msgid "Override directives"
 msgstr "Переопределить директивы"
 
+
+msgid "Migrate by job"
+msgstr "Migrate by job"
+
+msgid "Migrate by client"
+msgstr "Migrate by client"
+
+msgid "Migrate by volume"
+msgstr "Migrate by volume"
+
+msgid "Migrate by smallest volume"
+msgstr "Migrate by smallest volume"
+
+msgid "Migrate by oldest volume"
+msgstr "Migrate by oldest volume"
+
+msgid "Migrate using Pool occupancy"
+msgstr "Migrate using Pool occupancy"
+
+msgid "Migrate by Pool time"
+msgstr "Migrate by Pool time"
+
+msgid "Migrate by SQL query"
+msgstr "Migrate by SQL query"
+
+msgid "New migrate job wizard"
+msgstr "New migrate job wizard"
+
+msgid "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing i     t to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+msgstr "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing i     t to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+
+msgid "Step 2 - what you want to migrate"
+msgstr "Step 2 - what you want to migrate"
+
+msgid "Please select a pool from which you want to migrate data."
+msgstr "Please select a pool from which you want to migrate data."
+
+msgid "The source pool will be examined for finding backup jobs to migrate."
+msgstr "The source pool will be examined for finding backup jobs to migrate."
+
+msgid "Please select a storage using which you want to read migrate data."
+msgstr "Please select a storage using which you want to read migrate data."
+
+msgid "Because you selected migrate using Pool occupancy, to chosen source pool %pool will be added two directives: Migration Low Bytes and Migration High Bytes."
+msgstr "Because you selected migrate using Pool occupancy, to chosen source pool %pool will be added two directives: Migration Low Bytes and Migration High Bytes."
+
+msgid "Because you selected migrate using Pool time, to chosen source pool %pool will be added the Migration Time directive."
+msgstr "Because you selected migrate using Pool time, to chosen source pool %pool will be added the Migration Time directive."
+
+msgid "Step 3 - how would you like to migrate"
+msgstr "Step 3 - how would you like to migrate"
+
+msgid "Step 4 - where you like to migrate"
+msgstr "Step 4 - where you like to migrate"
+
+msgid "Please select a storage using which you want to write migrated data."
+msgstr "Please select a storage using which you want to write migrated data."
+
+msgid "Step 5 - migrate job options"
+msgstr "Step 5 - migrate job options"
+
+msgid "Purge jobs"
+msgstr "Purge jobs"
+
+msgid "Level, Client and FileSet are not used during migrate jobs running but they are required to define in migrate job resource as the standard Job directives."
+msgstr "Level, Client and FileSet are not used during migrate jobs running but they are required to define in migrate job resource as the standard Job directives."
+
+msgid "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+msgstr "Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon."
+
+msgid "New migrate job"
+msgstr "New migrate job"
+
+msgid "Please select the criteria that will be used for selecting backup jobs to migrate."
+msgstr "Please select the criteria that will be used for selecting backup jobs to migrate."
index 6ffe38c7ab09fd4a6161cff4565b7ff5183d3d52..985857fea433a31a1433e2a08313ba7e38d9e38c 100644 (file)
@@ -10,6 +10,7 @@
                <button type="button" class="w3-button w3-margin-bottom w3-green<%=empty($_SESSION['dir']) ? ' hide': ''%>" onclick="document.location.href='<%=$this->Service->constructUrl('NewResource', array('component_type' => 'dir', 'component_name' => $_SESSION['dir'], 'resource_type' => 'Job'))%>';"><i class="fa fa-plus"></i> &nbsp;<%[ Add job ]%></button>
                <button type="button" class="w3-button w3-margin-bottom w3-green<%=empty($_SESSION['dir']) ? ' hide': ''%>" onclick="document.location.href='<%=$this->Service->constructUrl('NewBackupJobWizard')%>';"><i class="fa fa-magic"></i> &nbsp;<%[ New backup job ]%></button>
                <button type="button" class="w3-button w3-margin-bottom w3-green<%=empty($_SESSION['dir']) ? ' hide': ''%>" onclick="document.location.href='<%=$this->Service->constructUrl('NewCopyJobWizard')%>';"><i class="fa fa-magic"></i> &nbsp;<%[ New copy job ]%></button>
+               <button type="button" class="w3-button w3-margin-bottom w3-green<%=empty($_SESSION['dir']) ? ' hide': ''%>" onclick="document.location.href='<%=$this->Service->constructUrl('NewMigrateJobWizard')%>';"><i class="fa fa-magic"></i> &nbsp;<%[ New migrate job ]%></button>
                <com:TActiveLinkButton
                        CssClass="w3-button w3-margin-bottom w3-green"
                        OnClick="loadRunJobModal"
index ffb83b850402a78a8b045033cc340924bf52c381..1900d16cdcf0aa4f6e33f9fca968c58f4c98efa5 100644 (file)
@@ -10,6 +10,7 @@
                <button type="button" class="w3-button w3-margin-bottom w3-green<%=empty($_SESSION['dir']) ? ' hide': ''%>" onclick="document.location.href='<%=$this->Service->constructUrl('NewResource', array('component_type' => 'dir', 'component_name' => $_SESSION['dir'], 'resource_type' => 'Job'))%>';"><i class="fa fa-plus"></i> &nbsp;<%[ Add job ]%></button>
                <button type="button" class="w3-button w3-margin-bottom w3-green<%=empty($_SESSION['dir']) ? ' hide': ''%>" onclick="document.location.href='<%=$this->Service->constructUrl('NewBackupJobWizard')%>';"><i class="fa fa-magic"></i> &nbsp;<%[ New backup job ]%></button>
                <button type="button" class="w3-button w3-margin-bottom w3-green<%=empty($_SESSION['dir']) ? ' hide': ''%>" onclick="document.location.href='<%=$this->Service->constructUrl('NewCopyJobWizard')%>';"><i class="fa fa-magic"></i> &nbsp;<%[ New copy job ]%></button>
+               <button type="button" class="w3-button w3-margin-bottom w3-green<%=empty($_SESSION['dir']) ? ' hide': ''%>" onclick="document.location.href='<%=$this->Service->constructUrl('NewMigrateJobWizard')%>';"><i class="fa fa-magic"></i> &nbsp;<%[ New migrate job ]%></button>
                <com:TActiveLinkButton
                        CssClass="w3-button w3-margin-bottom w3-green"
                        OnClick="loadRunJobModal"
diff --git a/gui/baculum/protected/Web/Pages/NewMigrateJobWizard.page b/gui/baculum/protected/Web/Pages/NewMigrateJobWizard.page
new file mode 100644 (file)
index 0000000..9389f45
--- /dev/null
@@ -0,0 +1,2076 @@
+<%@ MasterClass="Application.Web.Layouts.Wizard" Theme="Baculum-v2"%>
+<com:TContent ID="Wizard">
+       <com:TWizard ID="NewJobWizard"
+               CssClass="wizard"
+               StepStyle.CssClass="steps"
+               HeaderStyle.CssClass="wizard-body"
+               NavigationStyle.CssClass="w3-container"
+               NavigationStyle.CustomStyle="margin-bottom: 55px"
+               UseDefaultLayout="false"
+               ShowSideBar="false"
+               OnPreviousButtonClick="wizardPrev"
+               OnNextButtonClick="wizardNext"
+               OnCancelButtonClick="wizardStop"
+               OnCompleteButtonClick="wizardCompleted"
+               >
+               <prop:HeaderTemplate>
+                       <div class="w3-half">
+                               <div class="w3-third w3-padding-16">
+                                       <div class="step w3-padding w3-text-white w3-margin-right <%=($this->Parent->ActiveStepIndex === 0 ? 'w3-light-green' : 'w3-green')%>">
+                                               <div class="w3-left"><i class="fa fa-tasks w3-xxxlarge"></i></div>
+                                               <div class="w3-clear"></div>
+                                               <h4><com:TTranslate Text="General" /></h4>
+                                       </div>
+                               </div>
+                               <div class="w3-third w3-padding-16">
+                                       <div class="step w3-padding w3-text-white w3-margin-right <%=($this->Parent->ActiveStepIndex === 1 ? 'w3-light-green' : 'w3-green')%>">
+                                               <div class="w3-left"><i class="fa fa-upload w3-xxxlarge"></i></div>
+                                               <div class="w3-clear"></div>
+                                               <h4><com:TTranslate Text="What" /></h4>
+                                       </div>
+                               </div>
+                               <div class="w3-third w3-padding-16">
+                                       <div class="step w3-padding w3-text-white w3-margin-right <%=($this->Parent->ActiveStepIndex === 2 ? 'w3-light-green' : 'w3-green')%>">
+                                               <div class="w3-left"><i class="fa fa-question w3-xxxlarge"></i></div>
+                                               <div class="w3-clear"></div>
+                                               <h4><com:TTranslate Text="How" /></h4>
+                                       </div>
+                               </div>
+                       </div>
+                       <div class="w3-half">
+                               <div class="w3-third w3-padding-16">
+                                       <div class="step w3-padding w3-text-white w3-margin-right <%=($this->Parent->ActiveStepIndex === 3  ? 'w3-light-green' : 'w3-green')%>">
+                                               <div class="w3-left"><i class="fa fa-download w3-xxxlarge"></i></div>
+                                               <div class="w3-clear"></div>
+                                               <h4><com:TTranslate Text="Where" /></h4>
+                                       </div>
+                               </div>
+                               <div class="w3-third w3-padding-16">
+                                       <div class="step w3-padding w3-text-white w3-margin-right <%=($this->Parent->ActiveStepIndex === 4 ? 'w3-light-green' : 'w3-green')%>">
+                                               <div class="w3-left"><i class="fa fa-clipboard-list w3-xxxlarge"></i></div>
+                                               <div class="w3-clear"></div>
+                                               <h4><com:TTranslate Text="Options" /></h4>
+                                       </div>
+                               </div>
+                               <div class="w3-third w3-padding-16">
+                                       <div class="step w3-padding w3-text-white w3-margin-right <%=($this->Parent->ActiveStepIndex === 5 ? 'w3-light-green' : 'w3-green')%>">
+                                               <div class="w3-left"><i class="fa fa-paper-plane w3-xxxlarge"></i></div>
+                                               <div class="w3-clear"></div>
+                                               <h4><com:TTranslate Text="Summary" /></h4>
+                                       </div>
+                               </div>
+                       </div>
+                       <div class="step_title w3-panel w3-green w3-margin-right"><h3><%=$this->Parent->ActiveStep->Title%></h3></div>
+               </prop:HeaderTemplate>
+               <prop:StartNavigationTemplate>
+                       <div class="w3-center w3-section">
+                               <com:TLinkButton
+                                       CommandName="Cancel"
+                                       CausesValidation="false"
+                                       CssClass="w3-button w3-red"
+                               >
+                                       <i class="fa fa-times"></i> &nbsp;<%[ Cancel ]%>
+                               </com:TLinkButton>
+                               <com:TLinkButton
+                                       CommandName="NextStep"
+                                       ValidationGroup="NewMigrateJobDirective"
+                                       CssClass="w3-button w3-green"
+                               >
+                                       <%[ Next ]%>&nbsp; <i class="fa fa-angle-right"></i>
+                               </com:TLinkButton>
+                       </div>
+               </prop:StartNavigationTemplate>
+
+               <prop:StepNavigationTemplate>
+                       <div class="w3-center w3-section">
+                               <com:TLinkButton
+                                       CommandName="Cancel"
+                                       CausesValidation="false"
+                                       CssClass="w3-button w3-red"
+                               >
+                                       <i class="fa fa-times"></i> &nbsp;<%[ Cancel ]%>
+                               </com:TLinkButton>
+                               <com:TLinkButton
+                                       ID="PreviousStepBtn"
+                                       CommandName="PreviousStep"
+                                       CausesValidation="false"
+                                       CssClass="w3-button w3-green"
+                               >
+                                       <i class="fa fa-angle-left"></i> &nbsp;<%[ Previous ]%>
+                               </com:TLinkButton>
+                               <com:TLinkButton
+                                       CommandName="NextStep"
+                                       ValidationGroup="NewMigrateJobDirective"
+                                       CssClass="w3-button w3-green"
+                               >
+                                       <%[ Next ]%>&nbsp; <i class="fa fa-angle-right"></i>
+                               </com:TLinkButton>
+                       </div>
+               </prop:StepNavigationTemplate>
+               <prop:FinishNavigationTemplate>
+                       <div class="w3-center w3-section">
+                               <com:TLinkButton
+                                       CommandName="Cancel"
+                                       CausesValidation="false"
+                                       CssClass="w3-button w3-red"
+                               >
+                                       <i class="fa fa-times"></i> &nbsp;<%[ Cancel ]%>
+                               </com:TLinkButton>
+                               <com:TLinkButton
+                                       CommandName="PreviousStep"
+                                       CausesValidation="false"
+                                       CssClass="w3-button w3-green"
+                               >
+                                       <i class="fa fa-angle-left"></i> &nbsp;<%[ Previous ]%>
+                               </com:TLinkButton>
+                               <com:TLinkButton
+                                       CommandName="Complete"
+                                       CssClass="w3-button w3-green"
+                               >
+                                       <%[ Create job ]%> &nbsp;<i class="fa fa-paper-plane"></i>
+                               </com:TLinkButton>
+                       </div>
+                       </div>
+               </prop:FinishNavigationTemplate>
+               <com:TWizardStep ID="Step1" Title="<%[ Step 1 - basic information about new job ]%>" StepType="Auto">
+                       <div class="w3-container">
+                               <h2><%[ New migrate job wizard ]%></h2>
+                               <p><%[ Migrate jobs run moving backup jobs data from one volume to another. It is done by reading the previously backed up data from volume and writing it to another volume in a different pool. The file catalog records associated with the original backup jobs are purged. All process runs without using file daemon. ]%></p>
+                       </div>
+                       <div class="w3-half" style="float: none; margin: auto">
+                               <div class="w3-container w3-margin-top">
+                                       <com:Application.Web.Portlets.DirectiveTextBox
+                                               ID="Name"
+                                               DirectiveName="Name"
+                                               Label="Job Name"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="true"
+                                               Show="true"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                               </div>
+                               <div class="w3-container w3-margin-top">
+                                       <com:Application.Web.Portlets.DirectiveTextBox
+                                               ID="Description"
+                                               DirectiveName="Description"
+                                               Label="Description"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="false"
+                                               Show="true"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                               </div>
+                               <div class="w3-container w3-margin-top">
+                                       <com:Application.Web.Portlets.DirectiveComboBox
+                                               ID="JobDefs"
+                                               DirectiveName="JobDefs"
+                                               Label="JobDefs"
+                                               Show="true"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                               </div>
+                       </div>
+               </com:TWizardStep>
+               <com:TWizardStep ID="Step2" Title="<%[ Step 2 - what you want to migrate ]%>" StepType="Auto">
+                       <div class="w3-container">
+                               <h2><%[ Source Pool ]%></h2>
+                               <p><%[ Please select a pool from which you want to migrate data. ]%></p>
+                               <p><%[ The source pool will be examined for finding backup jobs to migrate. ]%></p>
+                       </div>
+                       <div class="w3-half" style="float: none; margin: auto">
+                               <div class="w3-container w3-margin-top">
+                                       <com:Application.Web.Portlets.DirectiveComboBox
+                                               ID="Pool"
+                                               DirectiveName="Pool"
+                                               Label="Source Pool"
+                                               Show="true"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="true"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               Attributes.onchange="set_storage_from_pool(); oVolumeList.show_volumes_in_pool_btn(this.value);oVolumeList.show_volumes_in_pool_table(false);"
+                                               />
+                               </div>
+                               <a id="volumes_in_pool_btn" href="javascript:void(0)" onclick="oVolumeList.load_data(document.getElementById('<%=$this->Pool->Directive->ClientID%>').value);" style="display: none; width: 300px; margin: 0 auto;"><%[ See volumes in selected pool ]%></a>
+                       </div>
+                       <div class="w3-container">
+                               <h2><%[ Source Storage ]%></h2>
+                               <p><%[ Please select a storage using which you want to read migrate data. ]%></p>
+                       </div>
+                       <div class="w3-half" style="float: none; margin: auto">
+                               <div class="w3-container w3-margin-top">
+                                       <com:Application.Web.Portlets.DirectiveComboBox
+                                               ID="SourceStorage"
+                                               DirectiveName="Storage"
+                                               Label="Source Storage"
+                                               Show="true"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="true"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                               </div>
+                               <com:TCallback ID="SetSourceStorageByPool" OnCallback="setSourceStorageByPool" />
+<script>
+function set_storage_from_pool() {
+       var cb = <%=$this->SetSourceStorageByPool->ActiveControl->Javascript%>;
+       cb.dispatch();
+}
+function set_storage_from_pool_cb(storage) {
+       if (storage) {
+               var st = document.getElementById('<%=$this->SourceStorage->Directive->ClientID%>');
+               st.value = storage;
+       }
+}
+</script>
+                       </div>
+                       <div id="source_pool_volume_list" class="w3-container w3-margin" style="display: none">
+                               <table id="volume_list" class="w3-table w3-striped w3-white w3-margin-bottom" style="width: 100%">
+                                       <thead>
+                                               <tr>
+                                                       <th></th>
+                                                       <th>MediaId</th>
+                                                       <th><%[ Name ]%></th>
+                                                       <th><%[ Slot ]%></th>
+                                                       <th>PoolId</th>
+                                                       <th><%[ Pool ]%></th>
+                                                       <th>InChanger</th>
+                                                       <th>StorageId</th>
+                                                       <th><%[ Storage ]%></th>
+                                                       <th>DeviceId</th>
+                                                       <th><%[ Vol. status ]%></th>
+                                                       <th><%[ Enabled ]%></th>
+                                                       <th><%[ Recycle ]%></th>
+                                                       <th>MediaType</th>
+                                                       <th>MediaTypeId</th>
+                                                       <th>LabelType</th>
+                                                       <th><%[ First written ]%></th>
+                                                       <th><%[ Last written ]%></th>
+                                                       <th><%[ Vol. bytes ]%></th>
+                                                       <th><%[ Max. vol. bytes ]%></th>
+                                                       <th><%[ Max. vol. jobs ]%></th>
+                                                       <th><%[ Max. vol. files ]%></th>
+                                                       <th><%[ Vol. capacity bytes ]%></th>
+                                                       <th><%[ Vol. abytes ]%></th>
+                                                       <th><%[ Vol. apadding ]%></th>
+                                                       <th><%[ Vol. hole bytes ]%></th>
+                                                       <th><%[ Vol. holes ]%></th>
+                                                       <th><%[ Vol. parts ]%></th>
+                                                       <th><%[ Vol. errors ]%></th>
+                                                       <th><%[ Vol. writes ]%></th>
+                                                       <th><%[ Label date ]%></th>
+                                                       <th><%[ Vol. jobs ]%></th>
+                                                       <th><%[ Vol. files ]%></th>
+                                                       <th><%[ Vol. blocks ]%></th>
+                                                       <th><%[ Vol. mounts ]%></th>
+                                                       <th><%[ Action on purge ]%></th>
+                                                       <th><%[ Vol. retention ]%></th>
+                                                       <th><%[ Cache retention ]%></th>
+                                                       <th><%[ Vol. use duration ]%></th>
+                                                       <th><%[ Media addressing ]%></th>
+                                                       <th><%[ Vol. read time ]%></th>
+                                                       <th><%[ Vol. write time ]%></th>
+                                                       <th><%[ Vol. type ]%></th>
+                                                       <th><%[ Vol. cloud parts ]%></th>
+                                                       <th><%[ Last part bytes ]%></th>
+                                                       <th><%[ End file ]%></th>
+                                                       <th><%[ End block ]%></th>
+                                                       <th>LocationId</th>
+                                                       <th><%[ Recycle count ]%></th>
+                                                       <th><%[ Initial write ]%></th>
+                                                       <th>ScratchPoolId</th>
+                                                       <th><%[ Scratch pool ]%></th>
+                                                       <th>RecyclePoolId</th>
+                                                       <th><%[ Recycle pool ]%></th>
+                                                       <th><%[ Comment ]%></th>
+                                                       <th><%[ When expire ]%></th>
+                                               </tr>
+                                       </thead>
+                                       <tbody id="pool_list_body"></tbody>
+                                       <tfoot>
+                                               <tr>
+                                                       <th></th>
+                                                       <th>MediaId</th>
+                                                       <th><%[ Name ]%></th>
+                                                       <th><%[ Slot ]%></th>
+                                                       <th>PoolId</th>
+                                                       <th><%[ Pool ]%></th>
+                                                       <th>InChanger</th>
+                                                       <th>StorageId</th>
+                                                       <th><%[ Storage ]%></th>
+                                                       <th>DeviceId</th>
+                                                       <th><%[ Vol. status ]%></th>
+                                                       <th><%[ Enabled ]%></th>
+                                                       <th><%[ Recycle ]%></th>
+                                                       <th>MediaType</th>
+                                                       <th>MediaTypeId</th>
+                                                       <th>LabelType</th>
+                                                       <th><%[ First written ]%></th>
+                                                       <th><%[ Last written ]%></th>
+                                                       <th><%[ Vol. bytes ]%></th>
+                                                       <th><%[ Max. vol. bytes ]%></th>
+                                                       <th><%[ Max. vol. jobs ]%></th>
+                                                       <th><%[ Max. vol. files ]%></th>
+                                                       <th><%[ Vol. capacity bytes ]%></th>
+                                                       <th><%[ Vol. abytes ]%></th>
+                                                       <th><%[ Vol. apadding ]%></th>
+                                                       <th><%[ Vol. hole bytes ]%></th>
+                                                       <th><%[ Vol. holes ]%></th>
+                                                       <th><%[ Vol. parts ]%></th>
+                                                       <th><%[ Vol. errors ]%></th>
+                                                       <th><%[ Vol. writes ]%></th>
+                                                       <th><%[ Label date ]%></th>
+                                                       <th><%[ Vol. jobs ]%></th>
+                                                       <th><%[ Vol. files ]%></th>
+                                                       <th><%[ Vol. blocks ]%></th>
+                                                       <th><%[ Vol. mounts ]%></th>
+                                                       <th><%[ Action on purge ]%></th>
+                                                       <th><%[ Vol. retention ]%></th>
+                                                       <th><%[ Cache retention ]%></th>
+                                                       <th><%[ Vol. use duration ]%></th>
+                                                       <th><%[ Media addressing ]%></th>
+                                                       <th><%[ Vol. read time ]%></th>
+                                                       <th><%[ Vol. write time ]%></th>
+                                                       <th><%[ Vol. type ]%></th>
+                                                       <th><%[ Vol. cloud parts ]%></th>
+                                                       <th><%[ Last part bytes ]%></th>
+                                                       <th><%[ End file ]%></th>
+                                                       <th><%[ End block ]%></th>
+                                                       <th>LocationId</th>
+                                                       <th><%[ Recycle count ]%></th>
+                                                       <th><%[ Initial write ]%></th>
+                                                       <th>ScratchPoolId</th>
+                                                       <th><%[ Scratch pool ]%></th>
+                                                       <th>RecyclePoolId</th>
+                                                       <th><%[ Recycle pool ]%></th>
+                                                       <th><%[ Comment ]%></th>
+                                                       <th><%[ When expire ]%></th>
+                                               </tr>
+                                       </tfoot>
+                               </table>
+                       </div>
+<com:TCallback ID="LoadVolumeList" OnCallback="loadVolumes" />
+<script>
+var oVolumeList = {
+       table: null,
+       ids: {
+               volume_list: 'volume_list',
+               volume_list_body: 'volume_list_body',
+               volumes_in_pool_btn: 'volumes_in_pool_btn',
+               source_pool_volume_list: 'source_pool_volume_list'
+       },
+       init: function(data) {
+               if (this.table) {
+                       var page = this.table.page();
+                       this.table.clear().rows.add(data).draw();
+                       this.table.page(page).draw(false);
+               } else {
+                       this.set_table(data);
+               }
+               this.show_volumes_in_pool_table(true);
+       },
+       update: function(data) {
+               oVolumeList.init(data);
+       },
+       load_data: function(pool) {
+               var cb = <%=$this->LoadVolumeList->ActiveControl->Javascript%>;
+               cb.setCallbackParameter(pool);
+               cb.dispatch();
+       },
+       set_table: function(data) {
+               this.table = $('#' + this.ids.volume_list).DataTable({
+                       data: data,
+                       deferRender: true,
+                       dom: 'lBfrtip',
+                       stateSave: true,
+                       buttons: [
+                               'copy', 'csv', 'colvis'
+                       ],
+                       columns: [
+                               {
+                                       className: 'details-control',
+                                       orderable: false,
+                                       data: null,
+                                       defaultContent: '<button type="button" class="w3-button w3-blue"><i class="fa fa-angle-down"></i></button>'
+                               },
+                               {data: 'mediaid'},
+                               {data: 'volumename'},
+                               {data: 'slot'},
+                               {
+                                       data: 'poolid',
+                                       visible: false
+                               },
+                               {
+                                       data: 'pool',
+                                       visible: false
+                               },
+                               {
+                                       data: 'inchanger',
+                                       render: function(data, type, row) {
+                                               return (data === 1) ? '<%[ Yes ]%>' : '<%[ No ]%>';
+                                       }
+                               },
+                               {
+                                       data: 'storageid',
+                                       visible: false
+                               },
+                               {
+                                       data: 'storage',
+                                       visible: false
+                               },
+                               {
+                                       data: 'deviceid',
+                                       visible: false
+                               },
+                               {data: 'volstatus'},
+                               {
+                                       data: 'enabled',
+                                       render: function(data, type, row) {
+                                               return (data === 1) ? '<%[ Yes ]%>' : '<%[ No ]%>';
+                                       },
+                                       visible: false
+                               },
+                               {
+                                       data: 'recycle',
+                                       render: function(data, type, row) {
+                                               return (data === 1) ? '<%[ Yes ]%>' : '<%[ No ]%>';
+                                       },
+                                       visible: false
+                               },
+                               {data: 'mediatype'},
+                               {
+                                       data: 'mediatypeid',
+                                       visible: false
+                               },
+                               {
+                                       data: 'labeltype',
+                                       visible: false
+                               },
+                               {
+                                       data: 'firstwritten',
+                                       render: render_date,
+                                       visible: false
+                               },
+                               {
+                                       data: 'lastwritten',
+                                       render: render_date
+                               },
+                               {
+                                       data: 'volbytes',
+                                       render: render_bytes
+                               },
+                               {
+                                       data: 'maxvolbytes',
+                                       render: render_bytes,
+                                       visible: false
+                               },
+                               {
+                                       data: 'maxvoljobs',
+                                       visible: false
+                               },
+                               {
+                                       data: 'maxvolfiles',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volcapacitybytes',
+                                       render: render_bytes,
+                                       visible: false
+                               },
+                               {
+                                       data: 'volabytes',
+                                       render: render_bytes,
+                                       visible: false
+                               },
+                               {
+                                       data: 'volapadding',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volholebytes',
+                                       render: render_bytes,
+                                       visible: false
+                               },
+                               {
+                                       data: 'volholes',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volparts',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volerrors',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volwrites',
+                                       visible: false
+                               },
+                               {
+                                       data: 'labeldate',
+                                       render: render_date,
+                                       visible: false
+                               },
+                               {
+                                       data: 'voljobs',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volfiles',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volblocks',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volmounts',
+                                       visible: false
+                               },
+                               {
+                                       data: 'actiononpurge',
+                                       render: function(data, type, row) {
+                                               return (data === 1) ? '<%[ Yes ]%>' : '<%[ No ]%>';
+                                       },
+                                       visible: false
+                               },
+                               {
+                                       data: 'volretention',
+                                       render: render_time_period,
+                                       visible: false
+                               },
+                               {
+                                       data: 'cacheretention',
+                                       render: render_time_period,
+                                       visible: false
+                               },
+                               {
+                                       data: 'voluseduration',
+                                       render: render_time_period,
+                                       visible: false
+                               },
+                               {
+                                       data: 'mediaaddressing',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volreadtime',
+                                       render: render_time_period,
+                                       visible: false
+                               },
+                               {
+                                       data: 'volwritetime',
+                                       render: render_time_period,
+                                       visible: false
+                               },
+                               {
+                                       data: 'voltype',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volcloudparts',
+                                       visible: false
+                               },
+                               {
+                                       data: 'lastpartbytes',
+                                       render: render_bytes,
+                                       visible: false
+                               },
+                               {
+                                       data: 'endfile',
+                                       visible: false
+                               },
+                               {
+                                       data: 'endblock',
+                                       visible: false
+                               },
+                               {
+                                       data: 'locationid',
+                                       visible: false
+                               },
+                               {
+                                       data: 'recyclecount',
+                                       visible: false
+                               },
+                               {
+                                       data: 'initialwrite',
+                                       visible: false
+                               },
+                               {
+                                       data: 'scratchpoolid',
+                                       visible: false
+                               },
+                               {
+                                       data: 'scratchpool',
+                                       visible: false
+                               },
+                               {
+                                       data: 'recyclepoolid',
+                                       visible: false
+                               },
+                               {
+                                       data: 'recyclepool',
+                                       visible: false
+                               },
+                               {
+                                       data: 'comment',
+                                       visible: false
+                               },
+                               {
+                                       data: 'whenexpire',
+                                       render: render_date_ex,
+                                       visible: false
+                               }
+                       ],
+                       responsive: {
+                               details: {
+                                       type: 'column'
+                               }
+                       },
+                       columnDefs: [{
+                               className: 'control',
+                               orderable: false,
+                               targets: 0
+                       },
+                       {
+                               className: "dt-center",
+                               targets: [ 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55 ]
+                       },
+                       {
+                               className: "dt-body-right",
+                               targets: [ 18 ]
+                       }],
+                       order: [3, 'asc'],
+                       initComplete: function () {
+                               this.api().columns([2, 3, 6, 10, 13]).every(function () {
+                                       var column = this;
+                                       var select = $('<select><option value=""></option></select>')
+                                       .appendTo($(column.footer()).empty())
+                                       .on('change', function () {
+                                               var val = dtEscapeRegex(
+                                                       $(this).val()
+                                               );
+                                               column
+                                               .search(val ? '^' + val + '$' : '', true, false)
+                                               .draw();
+                                       });
+                                       if (column[0][0] == 3) {
+                                               column.cells('', column[0]).render('display').unique().sort(sort_natural).each(function(d, j) {
+                                                       if (column.search() == '^' + dtEscapeRegex(d) + '$') {
+                                                               select.append('<option value="' + d + '" selected>' + d + '</option>');
+                                                       } else {
+                                                               select.append('<option value="' + d + '">' + d + '</option>');
+                                                       }
+                                               });
+                                       } else {
+                                               column.cells('', column[0]).render('display').unique().sort().each(function(d, j) {
+                                                       if (column.search() == '^' + dtEscapeRegex(d) + '$') {
+                                                               select.append('<option value="' + d + '" selected>' + d + '</option>');
+                                                       } else {
+                                                               select.append('<option value="' + d + '">' + d + '</option>');
+                                                       }
+                                               });
+                                       }
+                               });
+                       }
+               });
+       },
+       show_volumes_in_pool_btn: function(show) {
+               var volumes_in_pool_btn = document.getElementById(this.ids.volumes_in_pool_btn);
+               volumes_in_pool_btn.style.display = show ? 'block' : 'none';
+       },
+       show_volumes_in_pool_table: function(show) {
+               var source_pool_volume_list = document.getElementById(this.ids.source_pool_volume_list);
+               source_pool_volume_list.style.display = show ? 'block' : 'none';
+               if (show && this.table) {
+                       this.table.responsive.recalc();
+               }
+       }
+};
+</script>
+               </com:TWizardStep>
+               <com:TWizardStep ID="Step3" Title="<%[ Step 3 - how would you like to migrate ]%>" StepType="Auto">
+                       <div class="w3-container">
+                               <h2><%[ Backup jobs selection criteria ]%></h2>
+                               <p><%[ Please select the criteria that will be used for selecting backup jobs to migrate. ]%></p>
+                       </div>
+                       <div class="w3-half" style="float: none; margin: auto">
+                               <div class="w3-container w3-margin-top">
+                                       <com:Application.Web.Portlets.DirectiveComboBox
+                                               ID="SelectionType"
+                                               DirectiveName="SelectionType"
+                                               Label="Selection Type"
+                                               Show="true"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="true"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               Attributes.onchange="oSelectionType.show_opts(this.value, true);"
+                                               />
+                               </div>
+                       </div>
+                       <div id="selection_type_job" class="w3-half" style="float: none; display: none; margin: auto;">
+                               <div class="w3-container w3-margin-top" style="position: relative">
+                                       <com:Application.Web.Portlets.DirectiveTextBox
+                                               ID="SelectionPatternJob"
+                                               DirectiveName="SelectionPattern"
+                                               Label="Selection Pattern Job"
+                                               Show="true"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="false"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                                       <a id="selection_type_jobs_btn" href="javascript:void(0)" onclick="oJobList.load_data();" style="display: block; width: 300px; margin: 0 auto;"><%[ See backup jobs ]%></a>
+                               </div>
+                       </div>
+                       <div id="selection_type_client" class="w3-half" style="float: none; display: none; margin: auto;">
+                               <div class="w3-container w3-margin-top" style="position: relative">
+                                       <com:Application.Web.Portlets.DirectiveTextBox
+                                               ID="SelectionPatternClient"
+                                               DirectiveName="SelectionPattern"
+                                               Label="Selection Pattern Client"
+                                               Show="true"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="false"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                                       <a id="selection_type_clients_btn" href="javascript:void(0)" onclick="oClientList.load_data();" style="display: block; width: 300px; margin: 0 auto;"><%[ See clients ]%></a>
+                               </div>
+                       </div>
+                       <div id="selection_type_volume" class="w3-half" style="float: none; display: none; margin: auto;">
+                               <div class="w3-container w3-margin-top" style="position: relative">
+                                       <com:Application.Web.Portlets.DirectiveTextBox
+                                               ID="SelectionPatternVolume"
+                                               DirectiveName="SelectionPattern"
+                                               Label="Selection Pattern Volume"
+                                               Show="true"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="false"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                                       <a id="selection_type_volumes_btn" href="javascript:void(0)" onclick="oVolumeList.load_data();" style="display: block; width: 300px; margin: 0 auto;"><%[ See volumes ]%></a>
+                               </div>
+                       </div>
+                       <div id="selection_type_smallest_volume" style="display: none">
+                       </div>
+                       <div id="selection_type_oldest_volume" style="display: none">
+                       </div>
+                       <div id="selection_type_sql_query" style="display: none">
+                               <div class="w3-container w3-margin-top" style="position: relative">
+                                       <com:Application.Web.Portlets.DirectiveTextBox
+                                               ID="SelectionPatternSQLQuery"
+                                               DirectiveName="SelectionPattern"
+                                               Label="Selection Pattern SQL Query"
+                                               Show="true"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="false"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                               </div>
+                       </div>
+                       <div id="selection_type_jobs_table" class="w3-container w3-margin" style="display: none">
+                               <table id="job_list" class="w3-table w3-striped w3-hoverable w3-white w3-margin-bottom" style="width: 100%">
+                                       <thead>
+                                               <tr>
+                                                       <th></th>
+                                                       <th><%[ Name ]%></th>
+                                                       <th><%[ Type ]%></th>
+                                                       <th><%[ Enabled ]%></th>
+                                                       <th>Max. concur. jobs</th>
+                                                       <th><%[ Priority ]%></th>
+                                                       <th><%[ Actions ]%></th>
+                                               </tr>
+                                       </thead>
+                                       <tbody id="job_list_body"></tbody>
+                                       <tfoot>
+                                               <tr>
+                                                       <th></th>
+                                                       <th><%[ Name ]%></th>
+                                                       <th><%[ Type ]%></th>
+                                                       <th><%[ Enabled ]%></th>
+                                                       <th>Max. concur. jobs</th>
+                                                       <th><%[ Priority ]%></th>
+                                                       <th><%[ Actions ]%></th>
+                                               </tr>
+                                       </tfoot>
+                               </table>
+<com:TCallback ID="LoadJobList" OnCallback="loadJobList" />
+<script>
+var oJobList = {
+       ids: {
+               job_list: 'job_list',
+               job_list_body: 'job_list_body'
+       },
+       table: null,
+       init: function(data) {
+               oJobList.set_table(data);
+               oSelectionType.show_jobs_btn(false);
+               oSelectionType.show_jobs_table(true);
+               oJobList.table.responsive.recalc();
+       },
+       set_table: function(data) {
+               this.table = $('#' + this.ids.job_list).DataTable({
+                       data: data,
+                       deferRender: true,
+                       dom: 'lBfrtip',
+                       stateSave: true,
+                       buttons: [
+                               'copy', 'csv', 'colvis'
+                       ],
+                       columns: [
+                               {
+                                       className: 'details-control',
+                                       orderable: false,
+                                       data: null,
+                                       defaultContent: '<button type="button" class="w3-button w3-blue"><i class="fa fa-angle-down"></i></button>'
+                               },
+                               {
+                                       data: 'job',
+                                       responsivePriority: 1
+                               },
+                               {
+                                       data: 'type',
+                                       render: function(data, type, row) {
+                                               return JobType.get_type(data);
+                                       },
+                                       responsivePriority: 2
+                               },
+                               {
+                                       data: 'enabled',
+                                       render: function(data, type, row) {
+                                               return (data == 1 ? '<%[ Yes ]%>' : '<%[ No ]%>');
+                                       },
+                                       responsivePriority: 4
+                               },
+                               {data: 'maxjobs'},
+                               {
+                                       data: 'priority',
+                                       visible: false
+                               },
+                               {
+                                       data: 'job',
+                                       render: function(data, type, row) {
+                                               var btn = document.createElement('BUTTON');
+                                               btn.className = 'w3-button w3-green';
+                                               btn.type = 'button';
+                                               var i = document.createElement('I');
+                                               i.className = 'fa fa-crosshairs';
+                                               var label = document.createTextNode(' <%[ Pick job name ]%>');
+                                               btn.appendChild(i);
+                                               btn.innerHTML += '&nbsp';
+                                               btn.appendChild(label);
+                                               btn.setAttribute('onclick', "document.getElementById('<%=$this->SelectionPatternJob->Directive->ClientID%>').value = '" + data + "';");
+                                               return btn.outerHTML;
+                                       }
+                               }
+                       ],
+                       responsive: {
+                               details: {
+                                       type: 'column'
+                               }
+                       },
+                       columnDefs: [{
+                               className: 'control',
+                               orderable: false,
+                               targets: 0
+                       },
+                       {
+                               className: "dt-center",
+                               targets: [ 2, 3, 4, 5, 6 ]
+                       }],
+                       order: [1, 'asc'],
+                       initComplete: function () {
+                               this.api().columns([1, 3, 4, 5]).every(function () {
+                                       var column = this;
+                                       var select = $('<select><option value=""></option></select>')
+                                       .appendTo($(column.footer()).empty())
+                                       .on('change', function () {
+                                               var val = dtEscapeRegex(
+                                                       $(this).val()
+                                               );
+                                               column
+                                               .search(val ? '^' + val + '$' : '', true, false)
+                                               .draw();
+                                       });
+                                       column.cells('', column[0]).render('display').unique().sort().each(function(d, j) {
+                                               if (column.search() == '^' + dtEscapeRegex(d) + '$') {
+                                                       select.append('<option value="' + d + '" selected>' + d + '</option>');
+                                               } else {
+                                                       select.append('<option value="' + d + '">' + d + '</option>');
+                                               }
+                                       });
+                               });
+                       }
+               });
+       },
+       load_data: function() {
+               var cb = <%=$this->LoadJobList->ActiveControl->Javascript%>;
+               cb.dispatch();
+       }
+};
+</script>
+                       </div>
+                       <div id="selection_type_clients_table" class="w3-container w3-margin" style="display: none">
+                               <table id="client_list" class="w3-table w3-striped w3-hoverable w3-white w3-margin-bottom" style="width: 100%">
+                                       <thead>
+                                               <tr>
+                                                       <th></th>
+                                                       <th>ClientId</th>
+                                                       <th><%[ Name ]%></th>
+                                                       <th><%[ Uname ]%></th>
+                                                       <th><%[ AutoPrune ]%></th>
+                                                       <th><%[ Job retention ]%></th>
+                                                       <th><%[ File retention ]%></th>
+                                                       <th><%[ Actions ]%></th>
+                                               </tr>
+                                       </thead>
+                                       <tbody id="client_list_body"></tbody>
+                                       <tfoot>
+                                               <tr>
+                                                       <th></th>
+                                                       <th>ClientId</th>
+                                                       <th><%[ Name ]%></th>
+                                                       <th><%[ Uname ]%></th>
+                                                       <th><%[ AutoPrune ]%></th>
+                                                       <th><%[ Job retention ]%></th>
+                                                       <th><%[ File retention ]%></th>
+                                                       <th><%[ Actions ]%></th>
+                                               </tr>
+                                       </tfoot>
+                               </table>
+<com:TCallback ID="LoadClientList" OnCallback="loadClientList" />
+<script>
+var oClientList = {
+       ids: {
+               client_list: 'client_list',
+               client_list_body: 'client_list_body'
+       },
+       table: null,
+       init: function(data) {
+               oClientList.set_table(data);
+               oSelectionType.show_clients_btn(false);
+               oSelectionType.show_clients_table(true);
+               oClientList.table.responsive.recalc();
+       },
+       set_table: function(data) {
+               this.table = $('#' + this.ids.client_list).DataTable({
+                       data: data,
+                       deferRender: true,
+                       dom: 'lBfrtip',
+                       stateSave: true,
+                       buttons: [
+                               'copy', 'csv', 'colvis'
+                       ],
+                       columns: [
+                               {
+                                       className: 'details-control',
+                                       orderable: false,
+                                       data: null,
+                                       defaultContent: '<button type="button" class="w3-button w3-blue"><i class="fa fa-angle-down"></i></button>'
+                               },
+                               {data: 'clientid'},
+                               {data: 'name'},
+                               {data: 'uname'},
+                               {
+                                       data: 'autoprune',
+                                       render: function(data, type, row) {
+                                               return (data == 1 ? '<%[ Yes ]%>' : '<%[ No ]%>');
+                                       }
+                               },
+                               {
+                                       data: 'jobretention',
+                                       render: render_time_period
+                               },
+                               {
+                                       data: 'fileretention',
+                                       render: render_time_period
+                               },
+                               {
+                                       data: 'name',
+                                       render: function (data, type, row) {
+                                               var btn = document.createElement('BUTTON');
+                                               btn.className = 'w3-button w3-green';
+                                               btn.type = 'button';
+                                               var i = document.createElement('I');
+                                               i.className = 'fa fa-crosshairs';
+                                               var label = document.createTextNode(' <%[ Pick client name ]%>');
+                                               btn.appendChild(i);
+                                               btn.innerHTML += '&nbsp';
+                                               btn.appendChild(label);
+                                               btn.setAttribute('onclick', "document.getElementById('<%=$this->SelectionPatternClient->Directive->ClientID%>').value = '" + data + "';");
+                                               return btn.outerHTML;
+                                       }
+                               }
+                       ],
+                       responsive: {
+                               details: {
+                                       type: 'column'
+                               }
+                       },
+                       columnDefs: [{
+                               className: 'control',
+                               orderable: false,
+                               targets: 0
+                       },
+                       {
+                               className: "dt-center",
+                               targets: [ 1, 4, 5, 6, 7 ]
+                       }],
+                       order: [2, 'asc'],
+                       initComplete: function () {
+                               this.api().columns([2, 3, 4, 5, 6]).every(function () {
+                                       var column = this;
+                                       var select = $('<select><option value=""></option></select>')
+                                       .appendTo($(column.footer()).empty())
+                                       .on('change', function () {
+                                               var val = dtEscapeRegex(
+                                                       $(this).val()
+                                               );
+                                               column
+                                               .search(val ? '^' + val + '$' : '', true, false)
+                                               .draw();
+                                       });
+                                       if (column[0][0] == 5 || column[0][0] == 6) {
+                                               column.data().unique().sort(sort_natural).each(function (d, j) {
+                                                       var time = Units.format_time_period(d);
+                                                       var time_f = time.value + ' ' + time.format + ((time.value > 0) ? 's': '');
+                                                       if (column.search() == '^' + dtEscapeRegex(time_f) + '$') {
+                                                               select.append('<option value="' + time_f + '" selected>' + time_f + '</option>');
+                                                       } else {
+                                                               select.append('<option value="' + time_f + '">' + time_f + '</option>');
+                                                       }
+                                               });
+                                       } else {
+                                               column.cells('', column[0]).render('display').unique().sort().each(function(d, j) {
+                                                       if (d) {
+                                                               if (column.search() == '^' + dtEscapeRegex(d) + '$') {
+                                                                       select.append('<option value="' + d + '" selected>' + d + '</option>');
+                                                               } else {
+                                                                       select.append('<option value="' + d + '">' + d + '</option>');
+                                                               }
+                                                       }
+                                               });
+                                       }
+                               });
+                       }
+               });
+       },
+       load_data: function() {
+               var cb = <%=$this->LoadClientList->ActiveControl->Javascript%>;
+               cb.dispatch();
+       }
+};
+</script>
+                       </div>
+                       <div id="selection_type_volumes_table" class="w3-container w3-margin" style="display: none">
+                               <table id="volume_list" class="w3-table w3-striped w3-hoverable w3-white w3-margin-bottom" style="width: 100%">
+                                       <thead>
+                                               <tr>
+                                                       <th></th>
+                                                       <th>MediaId</th>
+                                                       <th><%[ Name ]%></th>
+                                                       <th><%[ Slot ]%></th>
+                                                       <th>PoolId</th>
+                                                       <th><%[ Pool ]%></th>
+                                                       <th>InChanger</th>
+                                                       <th>StorageId</th>
+                                                       <th><%[ Storage ]%></th>
+                                                       <th>DeviceId</th>
+                                                       <th><%[ Vol. status ]%></th>
+                                                       <th><%[ Enabled ]%></th>
+                                                       <th><%[ Recycle ]%></th>
+                                                       <th>MediaType</th>
+                                                       <th>MediaTypeId</th>
+                                                       <th>LabelType</th>
+                                                       <th><%[ First written ]%></th>
+                                                       <th><%[ Last written ]%></th>
+                                                       <th><%[ Vol. bytes ]%></th>
+                                                       <th><%[ Max. vol. bytes ]%></th>
+                                                       <th><%[ Max. vol. jobs ]%></th>
+                                                       <th><%[ Max. vol. files ]%></th>
+                                                       <th><%[ Vol. capacity bytes ]%></th>
+                                                       <th><%[ Vol. abytes ]%></th>
+                                                       <th><%[ Vol. apadding ]%></th>
+                                                       <th><%[ Vol. hole bytes ]%></th>
+                                                       <th><%[ Vol. holes ]%></th>
+                                                       <th><%[ Vol. parts ]%></th>
+                                                       <th><%[ Vol. errors ]%></th>
+                                                       <th><%[ Vol. writes ]%></th>
+                                                       <th><%[ Label date ]%></th>
+                                                       <th><%[ Vol. jobs ]%></th>
+                                                       <th><%[ Vol. files ]%></th>
+                                                       <th><%[ Vol. blocks ]%></th>
+                                                       <th><%[ Vol. mounts ]%></th>
+                                                       <th><%[ Action on purge ]%></th>
+                                                       <th><%[ Vol. retention ]%></th>
+                                                       <th><%[ Cache retention ]%></th>
+                                                       <th><%[ Vol. use duration ]%></th>
+                                                       <th><%[ Media addressing ]%></th>
+                                                       <th><%[ Vol. read time ]%></th>
+                                                       <th><%[ Vol. write time ]%></th>
+                                                       <th><%[ Vol. type ]%></th>
+                                                       <th><%[ Vol. cloud parts ]%></th>
+                                                       <th><%[ Last part bytes ]%></th>
+                                                       <th><%[ End file ]%></th>
+                                                       <th><%[ End block ]%></th>
+                                                       <th>LocationId</th>
+                                                       <th><%[ Recycle count ]%></th>
+                                                       <th><%[ Initial write ]%></th>
+                                                       <th>ScratchPoolId</th>
+                                                       <th><%[ Scratch pool ]%></th>
+                                                       <th>RecyclePoolId</th>
+                                                       <th><%[ Recycle pool ]%></th>
+                                                       <th><%[ Comment ]%></th>
+                                                       <th><%[ When expire ]%></th>
+                                                       <th><%[ Actions ]%></th>
+                                               </tr>
+                                       </thead>
+                                       <tbody id="pool_list_body"></tbody>
+                                       <tfoot>
+                                               <tr>
+                                                       <th></th>
+                                                       <th>MediaId</th>
+                                                       <th><%[ Name ]%></th>
+                                                       <th><%[ Slot ]%></th>
+                                                       <th>PoolId</th>
+                                                       <th><%[ Pool ]%></th>
+                                                       <th>InChanger</th>
+                                                       <th>StorageId</th>
+                                                       <th><%[ Storage ]%></th>
+                                                       <th>DeviceId</th>
+                                                       <th><%[ Vol. status ]%></th>
+                                                       <th><%[ Enabled ]%></th>
+                                                       <th><%[ Recycle ]%></th>
+                                                       <th>MediaType</th>
+                                                       <th>MediaTypeId</th>
+                                                       <th>LabelType</th>
+                                                       <th><%[ First written ]%></th>
+                                                       <th><%[ Last written ]%></th>
+                                                       <th><%[ Vol. bytes ]%></th>
+                                                       <th><%[ Max. vol. bytes ]%></th>
+                                                       <th><%[ Max. vol. jobs ]%></th>
+                                                       <th><%[ Max. vol. files ]%></th>
+                                                       <th><%[ Vol. capacity bytes ]%></th>
+                                                       <th><%[ Vol. abytes ]%></th>
+                                                       <th><%[ Vol. apadding ]%></th>
+                                                       <th><%[ Vol. hole bytes ]%></th>
+                                                       <th><%[ Vol. holes ]%></th>
+                                                       <th><%[ Vol. parts ]%></th>
+                                                       <th><%[ Vol. errors ]%></th>
+                                                       <th><%[ Vol. writes ]%></th>
+                                                       <th><%[ Label date ]%></th>
+                                                       <th><%[ Vol. jobs ]%></th>
+                                                       <th><%[ Vol. files ]%></th>
+                                                       <th><%[ Vol. blocks ]%></th>
+                                                       <th><%[ Vol. mounts ]%></th>
+                                                       <th><%[ Action on purge ]%></th>
+                                                       <th><%[ Vol. retention ]%></th>
+                                                       <th><%[ Cache retention ]%></th>
+                                                       <th><%[ Vol. use duration ]%></th>
+                                                       <th><%[ Media addressing ]%></th>
+                                                       <th><%[ Vol. read time ]%></th>
+                                                       <th><%[ Vol. write time ]%></th>
+                                                       <th><%[ Vol. type ]%></th>
+                                                       <th><%[ Vol. cloud parts ]%></th>
+                                                       <th><%[ Last part bytes ]%></th>
+                                                       <th><%[ End file ]%></th>
+                                                       <th><%[ End block ]%></th>
+                                                       <th>LocationId</th>
+                                                       <th><%[ Recycle count ]%></th>
+                                                       <th><%[ Initial write ]%></th>
+                                                       <th>ScratchPoolId</th>
+                                                       <th><%[ Scratch pool ]%></th>
+                                                       <th>RecyclePoolId</th>
+                                                       <th><%[ Recycle pool ]%></th>
+                                                       <th><%[ Comment ]%></th>
+                                                       <th><%[ When expire ]%></th>
+                                                       <th><%[ Actions ]%></th>
+                                               </tr>
+                                       </tfoot>
+                               </table>
+<com:TCallback ID="LoadVolumeList2" OnCallback="loadVolumes" />
+<script>
+var oVolumeList = {
+       table: null,
+       ids: {
+               volume_list: 'volume_list',
+               volume_list_body: 'volume_list_body'
+       },
+       init: function(data) {
+               oVolumeList.set_table(data);
+               oSelectionType.show_volumes_table(true);
+               oSelectionType.show_volumes_btn(false);
+               oVolumeList.table.responsive.recalc();
+       },
+       update: function(data) {
+               oVolumeList.init(data);
+       },
+       load_data: function() {
+               var cb = <%=$this->LoadVolumeList2->ActiveControl->Javascript%>;
+               cb.setCallbackParameter('<%=$this->Pool->getDirectiveValue()%>');
+               cb.dispatch();
+       },
+       set_table: function(data) {
+               this.table = $('#' + this.ids.volume_list).DataTable({
+                       data: data,
+                       deferRender: true,
+                       dom: 'lBfrtip',
+                       stateSave: true,
+                       buttons: [
+                               'copy', 'csv', 'colvis'
+                       ],
+                       columns: [
+                               {
+                                       className: 'details-control',
+                                       orderable: false,
+                                       data: null,
+                                       defaultContent: '<button type="button" class="w3-button w3-blue"><i class="fa fa-angle-down"></i></button>'
+                               },
+                               {data: 'mediaid'},
+                               {data: 'volumename'},
+                               {data: 'slot'},
+                               {
+                                       data: 'poolid',
+                                       visible: false
+                               },
+                               {
+                                       data: 'pool',
+                                       visible: false
+                               },
+                               {
+                                       data: 'inchanger',
+                                       render: function(data, type, row) {
+                                               return (data === 1) ? '<%[ Yes ]%>' : '<%[ No ]%>';
+                                       }
+                               },
+                               {
+                                       data: 'storageid',
+                                       visible: false
+                               },
+                               {
+                                       data: 'storage',
+                                       visible: false
+                               },
+                               {
+                                       data: 'deviceid',
+                                       visible: false
+                               },
+                               {data: 'volstatus'},
+                               {
+                                       data: 'enabled',
+                                       render: function(data, type, row) {
+                                               return (data === 1) ? '<%[ Yes ]%>' : '<%[ No ]%>';
+                                       },
+                                       visible: false
+                               },
+                               {
+                                       data: 'recycle',
+                                       render: function(data, type, row) {
+                                               return (data === 1) ? '<%[ Yes ]%>' : '<%[ No ]%>';
+                                       },
+                                       visible: false
+                               },
+                               {data: 'mediatype'},
+                               {
+                                       data: 'mediatypeid',
+                                       visible: false
+                               },
+                               {
+                                       data: 'labeltype',
+                                       visible: false
+                               },
+                               {
+                                       data: 'firstwritten',
+                                       render: render_date,
+                                       visible: false
+                               },
+                               {
+                                       data: 'lastwritten',
+                                       render: render_date
+                               },
+                               {
+                                       data: 'volbytes',
+                                       render: render_bytes
+                               },
+                               {
+                                       data: 'maxvolbytes',
+                                       render: render_bytes,
+                                       visible: false
+                               },
+                               {
+                                       data: 'maxvoljobs',
+                                       visible: false
+                               },
+                               {
+                                       data: 'maxvolfiles',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volcapacitybytes',
+                                       render: render_bytes,
+                                       visible: false
+                               },
+                               {
+                                       data: 'volabytes',
+                                       render: render_bytes,
+                                       visible: false
+                               },
+                               {
+                                       data: 'volapadding',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volholebytes',
+                                       render: render_bytes,
+                                       visible: false
+                               },
+                               {
+                                       data: 'volholes',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volparts',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volerrors',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volwrites',
+                                       visible: false
+                               },
+                               {
+                                       data: 'labeldate',
+                                       render: render_date,
+                                       visible: false
+                               },
+                               {
+                                       data: 'voljobs',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volfiles',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volblocks',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volmounts',
+                                       visible: false
+                               },
+                               {
+                                       data: 'actiononpurge',
+                                       render: function(data, type, row) {
+                                               return (data === 1) ? '<%[ Yes ]%>' : '<%[ No ]%>';
+                                       },
+                                       visible: false
+                               },
+                               {
+                                       data: 'volretention',
+                                       render: render_time_period,
+                                       visible: false
+                               },
+                               {
+                                       data: 'cacheretention',
+                                       render: render_time_period,
+                                       visible: false
+                               },
+                               {
+                                       data: 'voluseduration',
+                                       render: render_time_period,
+                                       visible: false
+                               },
+                               {
+                                       data: 'mediaaddressing',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volreadtime',
+                                       render: render_time_period,
+                                       visible: false
+                               },
+                               {
+                                       data: 'volwritetime',
+                                       render: render_time_period,
+                                       visible: false
+                               },
+                               {
+                                       data: 'voltype',
+                                       visible: false
+                               },
+                               {
+                                       data: 'volcloudparts',
+                                       visible: false
+                               },
+                               {
+                                       data: 'lastpartbytes',
+                                       render: render_bytes,
+                                       visible: false
+                               },
+                               {
+                                       data: 'endfile',
+                                       visible: false
+                               },
+                               {
+                                       data: 'endblock',
+                                       visible: false
+                               },
+                               {
+                                       data: 'locationid',
+                                       visible: false
+                               },
+                               {
+                                       data: 'recyclecount',
+                                       visible: false
+                               },
+                               {
+                                       data: 'initialwrite',
+                                       visible: false
+                               },
+                               {
+                                       data: 'scratchpoolid',
+                                       visible: false
+                               },
+                               {
+                                       data: 'scratchpool',
+                                       visible: false
+                               },
+                               {
+                                       data: 'recyclepoolid',
+                                       visible: false
+                               },
+                               {
+                                       data: 'recyclepool',
+                                       visible: false
+                               },
+                               {
+                                       data: 'comment',
+                                       visible: false
+                               },
+                               {
+                                       data: 'whenexpire',
+                                       render: render_date_ex,
+                                       visible: false
+                               },
+                               {
+                                       data: 'volumename',
+                                       render: function (data, type, row) {
+                                               var btn = document.createElement('BUTTON');
+                                               btn.className = 'w3-button w3-green';
+                                               btn.type = 'button';
+                                               var i = document.createElement('I');
+                                               i.className = 'fa fa-crosshairs';
+                                               var label = document.createTextNode(' <%[ Pick volume name ]%>');
+                                               btn.appendChild(i);
+                                               btn.innerHTML += '&nbsp';
+                                               btn.appendChild(label);
+                                               btn.setAttribute('onclick', "document.getElementById('<%=$this->SelectionPatternVolume->Directive->ClientID%>').value = '" + data + "';");
+                                               return btn.outerHTML;
+                                       }
+                               }
+                       ],
+                       responsive: {
+                               details: {
+                                       type: 'column'
+                               }
+                       },
+                       columnDefs: [{
+                               className: 'control',
+                               orderable: false,
+                               targets: 0
+                       },
+                       {
+                               className: "dt-center",
+                               targets: [ 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56 ]
+                       },
+                       {
+                               className: "dt-body-right",
+                               targets: [ 18 ]
+                       }],
+                       order: [3, 'asc'],
+                       initComplete: function () {
+                               this.api().columns([2, 3, 6, 10, 13]).every(function () {
+                                       var column = this;
+                                       var select = $('<select><option value=""></option></select>')
+                                       .appendTo($(column.footer()).empty())
+                                       .on('change', function () {
+                                               var val = dtEscapeRegex(
+                                                       $(this).val()
+                                               );
+                                               column
+                                               .search(val ? '^' + val + '$' : '', true, false)
+                                               .draw();
+                                       });
+                                       if (column[0][0] == 3) {
+                                               column.cells('', column[0]).render('display').unique().sort(sort_natural).each(function(d, j) {
+                                                       if (column.search() == '^' + dtEscapeRegex(d) + '$') {
+                                                               select.append('<option value="' + d + '" selected>' + d + '</option>');
+                                                       } else {
+                                                               select.append('<option value="' + d + '">' + d + '</option>');
+                                                       }
+                                               });
+                                       } else {
+                                               column.cells('', column[0]).render('display').unique().sort().each(function(d, j) {
+                                                       if (column.search() == '^' + dtEscapeRegex(d) + '$') {
+                                                               select.append('<option value="' + d + '" selected>' + d + '</option>');
+                                                       } else {
+                                                               select.append('<option value="' + d + '">' + d + '</option>');
+                                                       }
+                                               });
+                                       }
+                               });
+                       }
+               });
+       }
+};
+</script>
+                       </div>
+                       <div id="selection_type_pool_occupancy" style="display: none">
+                               <div class="w3-container w3-half w3-margin-top" style="float: none; margin: auto;">
+                                       <com:Application.Web.Portlets.DirectiveSize
+                                               ID="MigrationHighBytes"
+                                               DirectiveName="MigrationHighBytes"
+                                               Label="Migration High Bytes"
+                                               Show="true"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="false"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                               </div>
+                               <div class="w3-container w3-half w3-margin-top" style="float: none; margin: auto;">
+                                       <com:Application.Web.Portlets.DirectiveSize
+                                               ID="MigrationLowBytes"
+                                               DirectiveName="MigrationLowBytes"
+                                               Label="Migration Low Bytes"
+                                               Show="true"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="false"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                               </div>
+                       </div>
+                       <div id="selection_type_pool_time" style="display: none">
+                               <div class="w3-container w3-half w3-margin-top" style="float: none; margin: auto;">
+                                       <com:Application.Web.Portlets.DirectiveTimePeriod
+                                               ID="MigrationTime"
+                                               DirectiveName="MigrationTime"
+                                               Label="Migration Time"
+                                               Show="true"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="false"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                               </div>
+                       </div>
+                       <div id="modify_source_pool_window" class="w3-modal" style="display: none">
+                               <div class="w3-modal-content w3-card-4 w3-animate-zoom" style="width:600px">
+                                       <header class="w3-container w3-orange">
+                                               <span onclick="oSelectionType.show_modify_source_pool_modal(false);" class="w3-button w3-display-topright">×</span>
+                                               <h2><%[ Warning ]%></h2>
+                                       </header>
+                                       <div class="w3-panel w3-padding">
+                                               <p><strong><%[ Note. ]%></strong> <span id="modify_source_pool_txt"></span></p>
+                                       </div>
+                                       <footer class="w3-container w3-center">
+                                               <button type="button" class="w3-button w3-section w3-green" onclick="oSelectionType.show_modify_source_pool_modal(false);"><i class="fa fa-check"></i> &nbsp;<%[ OK ]%></button>
+                                       </footer>
+                               </div>
+                       </div>
+<script>
+var oSelectionType = {
+       ids: {
+               types: {
+                       Job: 'selection_type_job',
+                       Client: 'selection_type_client',
+                       Volume: 'selection_type_volume',
+                       SmallestVolume: 'selection_type_smallest_volume',
+                       OldestVolume: 'selection_type_oldest_volume',
+                       PoolOccupancy: 'selection_type_pool_occupancy',
+                       PoolTime: 'selection_type_pool_time',
+                       SQLQuery: 'selection_type_sql_query'
+               },
+               tables: {
+                       Job: 'selection_type_jobs_table',
+                       Client: 'selection_type_clients_table',
+                       Volume: 'selection_type_volumes_table'
+               },
+               btns: {
+                       Job: 'selection_type_jobs_btn',
+                       Client: 'selection_type_clients_btn',
+                       Volume: 'selection_type_volumes_btn'
+               },
+               windows: {
+                       modify_source_pool: 'modify_source_pool_window'
+               },
+               txts: {
+                       modify_source_pool: 'modify_source_pool_txt'
+               }
+       },
+       init: function() {
+               var value = document.getElementById('<%=$this->SelectionType->Directive->ClientID%>').value;
+               this.show_opts(value, false);
+       },
+       set_modify_source_pool_txt: function(type) {
+               var txt;
+               if (type === 'PoolOccupancy') {
+                       txt = '<%[ Because you selected migrate using Pool occupancy, to chosen source pool %pool will be added two directives: Migration Low Bytes and Migration High Bytes. ]%>'.replace('%pool', '<%=$this->Pool->getDirectiveValue()%>');
+               } else if (type == 'PoolTime') {
+                       txt = '<%[ Because you selected migrate using Pool time, to chosen source pool %pool will be added the Migration Time directive. ]%>'.replace('%pool', '<%=$this->Pool->getDirectiveValue()%>');
+               }
+               if (txt) {
+                       var el = document.getElementById(this.ids.txts.modify_source_pool);
+                       el.textContent = txt;
+               }
+       },
+       show_opts: function(type, manual) {
+               this.hide_all();
+               if (type) {
+                       var el = document.getElementById(this.ids.types[type]);
+                       el.style.display = '';
+                       if (type == 'Job' && oJobList.table) {
+                               this.show_jobs_table(true);
+                       } else if (type == 'Client' && oClientList.table) {
+                               this.show_clients_table(true);
+                       } else if (type == 'Volume' && oVolumeList.table) {
+                               this.show_volumes_table(true);
+                       } else if ((type == 'PoolOccupancy' || type == 'PoolTime') && manual) {
+                               this.set_modify_source_pool_txt(type);
+                               this.show_modify_source_pool_modal(true);
+                       }
+               }
+       },
+       hide_all: function() {
+               var type;
+               for (var type in this.ids.types) {
+                       type = document.getElementById(this.ids.types[type]);
+                       type.style.display = 'none';
+               }
+               var table;
+               for (var table in this.ids.tables) {
+                       table = document.getElementById(this.ids.tables[table]);
+                       table.style.display = 'none';
+               }
+       },
+       show_jobs_btn: function(show) {
+               var jobs_btn = document.getElementById(this.ids.btns.Job);
+               jobs_btn.style.display = show ? 'block' : 'none';
+       },
+       show_jobs_table: function(show) {
+               var jobs_list = document.getElementById(this.ids.tables.Job);
+               jobs_list.style.display = show ? 'block' : 'none';
+       },
+       show_clients_btn: function(show) {
+               var clients_btn = document.getElementById(this.ids.btns.Client);
+               clients_btn.style.display = show ? 'block' : 'none';
+       },
+       show_clients_table: function(show) {
+               var clients_list = document.getElementById(this.ids.tables.Client);
+               clients_list.style.display = show ? 'block' : 'none';
+       },
+       show_volumes_btn: function(show) {
+               var volumes_btn = document.getElementById(this.ids.btns.Volume);
+               volumes_btn.style.display = show ? 'block' : 'none';
+       },
+       show_volumes_table: function(show) {
+               var volume_list = document.getElementById(this.ids.tables.Volume);
+               volume_list.style.display = show ? 'block' : 'none';
+       },
+       show_modify_source_pool_modal: function(show) {
+               var win = document.getElementById(this.ids.windows.modify_source_pool);
+               win.style.display = show ? 'block' : 'none';
+       }
+};
+$(function() {
+       oSelectionType.init();
+});
+</script>
+               </com:TWizardStep>
+               <com:TWizardStep ID="Step4" Title="<%[ Step 4 - where you like to migrate ]%>" StepType="Auto">
+                       <div class="w3-container">
+                               <h2><%[ Destination Pool ]%></h2>
+                               <p><%[ Please select destination pool to which will be stored data. ]%></p>
+                       </div>
+                       <div class="w3-half" style="float: none; margin: auto">
+                               <div class="w3-container w3-margin-top">
+                                       <com:Application.Web.Portlets.DirectiveComboBox
+                                               ID="NextPool"
+                                               DirectiveName="NextPool"
+                                               Label="Destination Pool (NextPool)"
+                                               Show="true"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="true"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               Attributes.onchange="set_storage_from_nextpool();"
+                                               />
+                               </div>
+                       <com:TCallback ID="SetDestinationStorageByPool" OnCallback="setDestinationStorageByPool" />
+                       <com:TCallback ID="GetJobsUsingPool" OnCallback="getJobsUsingPool" />
+<script>
+var storage_from_pool;
+var previous_storage = '';
+function set_storage_from_nextpool() {
+       var cb = <%=$this->SetDestinationStorageByPool->ActiveControl->Javascript%>;
+       cb.dispatch();
+}
+function set_storage_from_pool_cb(storage) {
+       storage_from_pool = storage;
+       if (storage) {
+               var st = document.getElementById('<%=$this->DestinationStorage->Directive->ClientID%>');
+               st.value = storage;
+               previous_storage = storage;
+       }
+}
+function set_storage(storage) {
+       var pool = document.getElementById('<%=$this->NextPool->Directive->ClientID%>');
+       if (storage && pool.value && storage !== storage_from_pool) {
+               var param = {
+                       storage: storage,
+                       pool: pool.value,
+                       action: 'set_dest_storage'
+               };
+               var cb = <%=$this->GetJobsUsingPool->ActiveControl->Javascript%>;
+               cb.setCallbackParameter(param);
+               cb.dispatch();
+       }
+}
+
+function apply_storage() {
+       var storage = document.getElementById('<%=$this->DestinationStorage->Directive->ClientID%>');
+       previous_storage = storage.value;
+}
+
+function revert_storage() {
+       var storage = document.getElementById('<%=$this->DestinationStorage->Directive->ClientID%>');
+       storage.value = previous_storage;
+}
+</script>
+                       <div id="warning_message_box" class="w3-modal" style="display: none">
+                               <div class="w3-modal-content w3-card-4 w3-animate-zoom" style="width:600px">
+                                       <header class="w3-container w3-orange">
+                                               <span onclick="revert_storage(); document.getElementById('warning_message_box').style.display='none'" class="w3-button w3-display-topright">×</span>
+                                               <h2><%[ Warning ]%></h2>
+                                       </header>
+                                       <div class="w3-panel w3-padding">
+                                               <p><strong><%[ Note. ]%></strong> <span id="warning_message_note"></span></p>
+                                       </div>
+                                       <div class="w3-container">
+                                               <a href="javascript:void(0)" onclick="$('#warning_message_job_list').slideToggle();"><%[ See all jobs that use the pool ]%></a>
+                                       </div>
+                                       <div id="warning_message_job_list" class="w3-panel w3-padding" style="display: none">
+                                               <ul id="warning_message_jobs"></ul>
+                                       </div>
+                                       <footer class="w3-container w3-center">
+                                               <button type="button" class="w3-button w3-section w3-red" onclick="revert_storage(); document.getElementById('warning_message_box').style.display='none'"><i class="fa fa-times"></i> &nbsp;<%[ Cancel ]%></button>
+                                               <button type="button" class="w3-button w3-section w3-green" onclick="apply_storage(); document.getElementById('warning_message_box').style.display='none'"><i class="fa fa-check"></i> &nbsp;<%[ OK ]%></button>
+                                       </footer>
+                               </div>
+                       </div>
+<script>
+function show_storage_warning(storage, pool, jobs) {
+       if (jobs.length == 0) {
+               previous_storage = storage;
+       }
+       var msg = '<%[ To chosen destination pool %pool will be assigned new Storage %storage. This action can affect all jobs (listed below) that use this pool. Are you sure you want to assign the storage %storage to pool %pool? ]%>';
+       msg = msg.replace(/%pool/g, pool);
+       msg = msg.replace(/%storage/g, storage);
+       var warn_box = document.getElementById('warning_message_box');
+       var warn_msg = document.getElementById('warning_message_note');
+       var ul = document.getElementById('warning_message_jobs');
+       ul.innerHTML = '';
+       var li, txt;
+       for (var i = 0; i < jobs.length; i++) {
+               li = document.createElement('LI');
+               li.textContent = jobs[i];
+               ul.appendChild(li);
+       }
+       warn_msg.textContent = msg;
+       warn_box.style.display = 'block';
+}
+</script>
+                       </div>
+                       <div class="w3-container">
+                               <h2><%[ Destination Storage ]%></h2>
+                               <p><%[ Please select a storage using which you want to write migrated data. ]%></p>
+                       </div>
+                       <div class="w3-half" style="float: none; margin: auto">
+                               <div class="w3-container w3-margin-top">
+                                       <com:Application.Web.Portlets.DirectiveComboBox
+                                               ID="DestinationStorage"
+                                               DirectiveName="Storage"
+                                               Label="Destination Storage"
+                                               Show="true"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="true"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               Attributes.onchange="set_storage(this.value);"
+                                               />
+                               </div>
+                       </div>
+               </com:TWizardStep>
+               <com:TWizardStep ID="Step5" Title="<%[ Step 5 - migrate job options ]%>" StepType="Auto">
+                       <div class="w3-container">
+                               <h2><%[ Purge jobs ]%></h2>
+                       </div>
+                       <div class="w3-half" style="float: none; margin: auto">
+                               <div class="w3-container w3-margin-top">
+                                       <com:Application.Web.Portlets.DirectiveCheckBox
+                                               ID="PurgeMigrationJob"
+                                               DirectiveName="PurgeMigrationJob"
+                                               DefaultValue="0"
+                                               Label="Purge Migration Job"
+                                               Show="true"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                               </div>
+                       </div>
+                       <div class="w3-container">
+                               <h2><%[ Limits ]%></h2>
+                       </div>
+                       <div class="w3-half" style="float: none; margin: auto">
+                               <div class="w3-container w3-margin-top">
+                                       <com:Application.Web.Portlets.DirectiveTextBox
+                                               ID="MaximumSpawnedJobs"
+                                               DirectiveName="MaximumSpawnedJobs"
+                                               DefaultValue="600"
+                                               Label="Maximum Spawned Jobs"
+                                               Show="true"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                               </div>
+                       </div>
+                       <div class="w3-container">
+                               <h2><%[ Schedule ]%></h2>
+                       </div>
+                       <div class="w3-half" style="float: none; margin: auto">
+                               <div class="w3-container w3-margin-top">
+                                       <com:Application.Web.Portlets.DirectiveComboBox
+                                               ID="Schedule"
+                                               DirectiveName="Schedule"
+                                               Label="Schedule"
+                                               Show="true"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                               </div>
+                       </div>
+                       <div class="w3-container">
+                               <h2><%[ Messages ]%></h2>
+                       </div>
+                       <div class="w3-half" style="float: none; margin: auto">
+                               <div class="w3-container w3-margin-top">
+                                       <com:Application.Web.Portlets.DirectiveComboBox
+                                               ID="Messages"
+                                               DirectiveName="Messages"
+                                               Label="Messages"
+                                               Show="true"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="true"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                               </div>
+                       </div>
+                       <div class="w3-half" style="float: none; margin: auto">
+                               <a href="javascript:void(0)" onclick="$('#migrate_job_wizard_other_options').slideToggle();"><%[ Other options ]%></a>
+                       </div>
+                       <div id="migrate_job_wizard_other_options" class="w3-half" style="float: none; margin: auto; display: none;">
+                               <p><%[ Level, Client and FileSet are not used during migrate jobs running but they are required to define in migrate job resource as the standard Job directives. ]%></p>
+                               <div class="w3-container w3-margin-top">
+                                       <com:Application.Web.Portlets.DirectiveComboBox
+                                               ID="Level"
+                                               DirectiveName="Level"
+                                               Label="Level"
+                                               Show="true"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="true"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                               </div>
+                               <div class="w3-container w3-margin-top">
+                                       <com:Application.Web.Portlets.DirectiveComboBox
+                                               ID="Client"
+                                               DirectiveName="Client"
+                                               Label="Client"
+                                               Show="true"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="true"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                               </div>
+                               <div class="w3-container w3-margin-top">
+                                       <com:Application.Web.Portlets.DirectiveComboBox
+                                               ID="FileSet"
+                                               DirectiveName="Fileset"
+                                               Label="FileSet"
+                                               Show="true"
+                                               ValidationGroup="NewMigrateJobDirective"
+                                               Required="true"
+                                               ShowResetButton="false"
+                                               ShowRemoveButton="false"
+                                               />
+                               </div>
+                       </div>
+               </com:TWizardStep>
+               <com:TWizardStep ID="Step6" Title="<%[ Step 6 - summary ]%>" StepType="Finish">
+                       <fieldset>
+                               <legend><%[ General ]%></legend>
+                               <div class="w3-container w3-padding-small">
+                                       <div class="w3-quarter">Job Name</div>
+                                       <div class="w3-threequarter bold"><%=$this->Name->getDirectiveValue()%></div>
+                               </div>
+                               <div class="w3-container w3-padding-small">
+                                       <div class="w3-quarter">Description</div>
+                                       <div class="w3-threequarter bold"><%=$this->Description->getDirectiveValue() ?: '-'%></div>
+                               </div>
+                               <div class="w3-container w3-padding-small">
+                                       <div class="w3-quarter">JobDefs</div>
+                                       <div class="w3-threequarter bold"><%=$this->JobDefs->getDirectiveValue() ?: '-'%></div>
+                               </div>
+                       </fieldset>
+                       <fieldset>
+                               <legend><%[ What ]%></legend>
+                               <div class="w3-container w3-padding-small">
+                                       <div class="w3-quarter">Source Pool</div>
+                                       <div class="w3-threequarter bold">
+                                               <%=$this->Pool->getDirectiveValue()%>
+                                               <span class="w3-small normal"><%=$this->isInJobDefs('Pool', $this->Pool->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%></span>
+                                       </div>
+                               </div>
+                               <div class="w3-container w3-padding-small">
+                                       <div class="w3-quarter">Source Storage</div>
+                                       <div class="w3-threequarter bold">
+                                               <%=$this->SourceStorage->getDirectiveValue()%>
+                                               <span class="w3-small normal"><%=$this->isInJobDefs('Storage', $this->SourceStorage->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%></span>
+                                       </div>
+                               </div>
+                       </fieldset>
+                       <fieldset>
+                               <legend><%[ How ]%></legend>
+                               <div class="w3-container w3-padding-small">
+                                       <div class="w3-quarter">Selection Type</div>
+                                       <div class="w3-threequarter bold">
+                                               <%=$this->sel_types[$this->SelectionType->getDirectiveValue()]%>
+                                               <span class="w3-small normal"><%=$this->isInJobDefs('SelectionType', $this->SelectionType->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%></span>
+                                       </div>
+                               </div>
+                               <div class="w3-container w3-padding-small">
+                                       <div class="w3-quarter">Selection Pattern</div>
+                                       <div class="w3-threequarter bold">
+                                               <%=$this->getPage()->getSelectionPatternValue() ?: '-'%>
+                                               <span class="w3-small normal"><%=$this->isInJobDefs('SelectionPattern', ($this->getSelectionPatternControl() ? $this->getSelectionPatternControl()->getDirectiveValue() : '')) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%></span>
+                                       </div>
+                               </div>
+                               <div class="w3-container w3-padding-small" style="display: <%=$this->SelectionType->getDirectiveValue() == 'PoolOccupancy' ? 'block' : 'none'%>">
+                                       <div class="w3-quarter">Migration High Bytes</div>
+                                       <div class="w3-threequarter bold">
+                                               <%=$this->MigrationHighBytes->Directive->getText()%> <%=$this->MigrationHighBytes->SizeFormat->getSelectedItem()->getText()%>
+                                               <span class="w3-small normal"><%=$this->isInJobDefs('MigrationHighBytes', ($this->MigrationHighBytes->getValue() ? $this->MigrationHighBytes->getValue() : '')) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%></span>
+                                       </div>
+                               </div>
+                               <div class="w3-container w3-padding-small" style="display: <%=$this->SelectionType->getDirectiveValue() == 'PoolOccupancy' ? 'block' : 'none'%>">
+                                       <div class="w3-quarter">Migration Low Bytes</div>
+                                       <div class="w3-threequarter bold">
+                                               <%=$this->MigrationLowBytes->Directive->getText()%> <%=$this->MigrationLowBytes->SizeFormat->getSelectedItem()->getText()%>
+                                               <span class="w3-small normal"><%=$this->isInJobDefs('MigrationLowBytes', ($this->MigrationLowBytes->getValue() ? $this->MigrationLowBytes->getValue() : '')) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%></span>
+                                       </div>
+                               </div>
+                               <div class="w3-container w3-padding-small" style="display: <%=$this->SelectionType->getDirectiveValue() == 'PoolTime' ? 'block' : 'none'%>">
+                                       <div class="w3-quarter">Migration Time</div>
+                                       <div class="w3-threequarter bold">
+                                               <%=$this->MigrationTime->Directive->getText()%> <%=$this->MigrationTime->TimeFormat->getSelectedItem()->getText()%>
+                                               <span class="w3-small normal"><%=$this->isInJobDefs('MigrationTime', ($this->MigrationTime->getValue() ? $this->MigrationTime->getValue() : '')) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%></span>
+                                       </div>
+                               </div>
+                       </fieldset>
+                       <fieldset>
+                               <legend><%[ Where ]%></legend>
+                               <div class="w3-container w3-padding-small">
+                                       <div class="w3-quarter">Destination Pool (NextPool)</div>
+                                       <div class="w3-threequarter bold">
+                                               <%=$this->NextPool->getDirectiveValue()%>
+                                               <span class="w3-small normal"><%=$this->isInJobDefs('NextPool', $this->Pool->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%></span>
+                                       </div>
+                               </div>
+                               <div class="w3-container w3-padding-small">
+                                       <div class="w3-quarter">Destination Storage</div>
+                                       <div class="w3-threequarter bold">
+                                               <%=$this->DestinationStorage->getDirectiveValue()%>
+                                       </div>
+                               </div>
+                       </fieldset>
+                       <fieldset>
+                               <legend><%[ Options ]%></legend>
+                               <div class="w3-container w3-padding-small">
+                                       <div class="w3-quarter">Purge Migration Job</div>
+                                       <div class="w3-threequarter bold">
+                                               <%=$this->PurgeMigrationJob->getValue() ? Prado::localize('Yes') : Prado::localize('No')%>
+                                               <span class="w3-small normal"><%=$this->isInJobDefs('PurgeMigrationJob', $this->PurgeMigrationJob->getValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%></span>
+                                       </div>
+                               </div>
+                               <div class="w3-container w3-padding-small">
+                                       <div class="w3-quarter">Maximum Spawned Jobs</div>
+                                       <div class="w3-threequarter bold">
+                                               <%=$this->MaximumSpawnedJobs->getDirectiveValue() ?: '-'%>
+                                               <span class="w3-small normal"><%=$this->isInJobDefs('MaximumSpawnedJobs', $this->MaximumSpawnedJobs->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%></span>
+                                       </div>
+                               </div>
+                               <div class="w3-container w3-padding-small">
+                                       <div class="w3-quarter">Schedule</div>
+                                       <div class="w3-threequarter bold">
+                                               <%=$this->Schedule->getDirectiveValue() ?: '-' %>
+                                               <span class="w3-small normal"><%=$this->isInJobDefs('Schedule', $this->Schedule->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%></span>
+                                       </div>
+                               </div>
+                               <div class="w3-container w3-padding-small">
+                                       <div class="w3-quarter">Messages</div>
+                                       <div class="w3-threequarter bold">
+                                               <%=$this->Messages->getDirectiveValue() ?: '-'%>
+                                               <span class="w3-small normal"><%=$this->isInJobDefs('Messages', $this->Messages->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%></span>
+                                       </div>
+                               </div>
+                               <div class="w3-container w3-padding-small">
+                                       <div class="w3-quarter">Level</div>
+                                       <div class="w3-threequarter bold">
+                                               <%=$this->Level->getDirectiveValue() ?: '-'%>
+                                               <span class="w3-small normal">(<%[ Not used ]%>) <%=$this->isInJobDefs('Level', $this->Level->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%></span>
+                                       </div>
+                               </div>
+                               <div class="w3-container w3-padding-small">
+                                       <div class="w3-quarter">Client</div>
+                                       <div class="w3-threequarter bold">
+                                               <%=$this->Client->getDirectiveValue()%>
+                                               <span class="w3-small normal">(<%[ Not used ]%>) <%=$this->isInJobDefs('Client', $this->Client->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%></span>
+                                       </div>
+                               </div>
+                               <div class="w3-container w3-padding-small">
+                                       <div class="w3-quarter">FileSet</div>
+                                       <div class="w3-threequarter bold">
+                                               <%=$this->FileSet->getDirectiveValue()%>
+                                               <span class="w3-small normal">(<%[ Not used ]%>) <%=$this->isInJobDefs('Fileset', $this->FileSet->getDirectiveValue()) ? ' (' . Prado::localize('inherited from JobDefs') . ')': ''%></span>
+                                       </div>
+                               </div>
+                       </fieldset>
+                       <com:TActiveLabel ID="CreateResourceErrorMsg" Display="None" CssClass="w3-text-red"></com:TActiveLabel>
+               </com:TWizardStep>
+       </com:TWizard>
+</com:TContent>
diff --git a/gui/baculum/protected/Web/Pages/NewMigrateJobWizard.php b/gui/baculum/protected/Web/Pages/NewMigrateJobWizard.php
new file mode 100644 (file)
index 0000000..be106dc
--- /dev/null
@@ -0,0 +1,788 @@
+<?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.Class.BaculumWebPage');
+Prado::using('System.Web.UI.ActiveControls.TActiveLabel');
+Prado::using('System.Web.UI.WebControls.TWizard');
+
+/**
+ * New migrate job wizard page.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category Page
+ * @package Baculum Web
+ */
+class NewMigrateJobWizard extends BaculumWebPage {
+
+       const PREV_STEP = 'PrevStep';
+       const JOBDEFS = 'JobDefs';
+
+       /**
+        * Stores available selection types.
+        *
+        * @var array
+        */
+       public $sel_types = [];
+
+       public function onInit($param) {
+               parent::onInit($param);
+               $this->sel_types = [
+                       'Job' => Prado::localize('Migrate by job'),
+                       'Client' => Prado::localize('Migrate by client'),
+                       'Volume' => Prado::localize('Migrate by volume'),
+                       'SmallestVolume' => Prado::localize('Migrate by smallest volume'),
+                       'OldestVolume' => Prado::localize('Migrate by oldest volume'),
+                       'PoolOccupancy' => Prado::localize('Migrate using Pool occupancy'),
+                       'PoolTime' => Prado::localize('Migrate by Pool time'),
+                       'SQLQuery' => Prado::localize('Migrate by SQL query')
+               ];
+       }
+
+       public function onPreRender($param) {
+               parent::onPreRender($param);
+               if ($this->IsCallBack) {
+                       return;
+               }
+               $step_index = $this->NewJobWizard->getActiveStepIndex();
+               $prev_step = $this->getPrevStep();
+               $this->setPrevStep($step_index);
+               if ($prev_step > $step_index) {
+                       return;
+               }
+               switch ($step_index) {
+                       case 0: {
+                               $this->loadJobDefs();
+                               break;
+                       }
+                       case 1: {
+                               $this->setupJobDefs();
+                               $this->loadPools();
+                               $this->loadSourceStorages();
+                               break;
+                       }
+                       case 2: {
+                               $this->loadSelectionTypes();
+                               break;
+                       }
+                       case 3: {
+                               $this->loadNextPools();
+                               $this->loadDestinationStorages();
+                               break;
+                       }
+                       case 4: {
+                               $this->loadSchedules();
+                               $this->loadMessages();
+                               $this->loadLevels();
+                               $this->loadClients();
+                               $this->loadFileSets();
+                               break;
+                       }
+               }
+       }
+
+       /**
+        * Wizard previous button callback actions.
+        *
+        * @param TWizard $sender sender object
+        * @param TWizardNavigationEventParameter $param sender parameters
+        * @return none
+        */
+       public function wizardPrev($sender, $param) {
+       }
+
+       /**
+        * Wizard next button callback actions.
+        *
+        * @param TWizard $sender sender object
+        * @param TWizardNavigationEventParameter $param sender parameters
+        * @return none
+        */
+       public function wizardNext($sender, $param) {
+       }
+
+       /**
+        * Load JobDefs (step 1).
+        *
+        * @return none
+        */
+       public function loadJobDefs() {
+               $jobdefs_list = [];
+               $jobdefs = $this->getModule('api')->get([
+                       'config',
+                       'dir',
+                       'jobdefs']
+               );
+               if ($jobdefs->error === 0) {
+                       for ($i = 0; $i < count($jobdefs->output); $i++) {
+                               $jobdefs_list[] = $jobdefs->output[$i]->JobDefs->Name;
+                       }
+                       asort($jobdefs_list);
+                       $this->JobDefs->setData($jobdefs_list);
+                       $this->JobDefs->createDirective();
+               }
+       }
+
+       /**
+        * Setup and remember selected JobDefs values to use in next wizard steps.
+        *
+        * @return none
+        */
+       public function setupJobDefs() {
+               $directive_value = $this->JobDefs->getDirectiveValue();
+               if (is_null($directive_value)) {
+                       return;
+               }
+               $jobdefs = $directive_value;
+               $result = $this->getModule('api')->get([
+                       'config',
+                       'dir',
+                       'jobdefs',
+                       $jobdefs
+               ]);
+               if ($result->error === 0) {
+                       $value = (array)$result->output;
+                       $this->setJobDefs($value);
+               }
+       }
+
+       /**
+        * Check if directive with given value exists in used JobDefs.
+        *
+        * @param string $directive_name directive name
+        * @param string $directive_value directive value
+        * @return boolean true if directive exists in JobDefs, otherwise false
+        */
+       public function isInJobDefs($directive_name, $directive_value) {
+               $jobdefs = $this->getJobDefs();
+               $ret = false;
+               if ($directive_name === 'Storage') {
+                       $ret = (key_exists($directive_name, $jobdefs) && $jobdefs[$directive_name][0] === $directive_value);
+               } else {
+                       $ret = (key_exists($directive_name, $jobdefs) && $jobdefs[$directive_name] === $directive_value);
+               }
+               return $ret;
+       }
+
+       /**
+        * Set pool type controls (Pool, NextPool ...etc.)
+        *
+        * @param string $name pool type directive name
+        * @param object $control different type of controls (usually DirectiveComboBox)
+        * @return none
+        */
+       public function setPools($name, $control) {
+               $pool_list = [];
+               $pools = $this->getModule('api')->get(['config', 'dir', 'pool'])->output;
+               for ($i = 0; $i < count($pools); $i++) {
+                       $pool_list[] = $pools[$i]->Pool->Name;
+               }
+               asort($pool_list);
+               $control->setData($pool_list);
+               $jobdefs = $this->getJobDefs();
+               if (key_exists($name, $jobdefs) && is_null($control->getDirectiveValue())) {
+                       $control->setDirectiveValue($jobdefs[$name]);
+               }
+               $control->createDirective();
+       }
+
+       /**
+        * Load pool list (step 2).
+        *
+        * @return none
+        */
+       public function loadPools() {
+               $this->setPools('Pool', $this->Pool);
+       }
+
+       /**
+        * Load volumes to display while source pool is configured.
+        *
+        * @param TCallback $sender callback object
+        * @param TCallbackEventParameter $param callback parameter
+        * @return none
+        */
+       public function loadVolumes($sender, $param) {
+               $pool = $param->getCallbackParameter();
+               $volumes = $this->getVolumes($pool);
+               $this->getCallbackClient()->callClientFunction(
+                       'oVolumeList.update',
+                       [$volumes]
+               );
+       }
+
+       /**
+        * Get volume list for given pool.
+        *
+        * @param string $pool pool name
+        * @return array volume list or empty array on error
+        */
+       public function getVolumes($pool) {
+               $poolid = null;
+               $result = $this->getModule('api')->get(['pools']);
+               if ($result->error === 0) {
+                       for ($i = 0; $i < count($result->output); $i++) {
+                               if ($pool === $result->output[$i]->name) {
+                                       $poolid = $result->output[$i]->poolid;
+                                       break;
+                               }
+                       }
+               }
+               $ret = [];
+               if ($poolid) {
+                       $result = $this->getModule('api')->get(
+                               ['pools', $poolid, 'volumes']
+                       );
+                       if ($result->error === 0) {
+                               $ret = $result->output;
+                       }
+               }
+               return $ret;
+       }
+
+       /**
+        * Load source storage list (step 2).
+        *
+        * @return none
+        */
+       public function loadSourceStorages() {
+               $this->setStorages($this->SourceStorage);
+       }
+
+       /**
+        * Set source storage control basing on pool configuration.
+        *
+        * @param TCallback $sender callback object
+        * @param TCallbackEventParameter $param callback parameter
+        * @return none
+        */
+       public function setSourceStorageByPool($sender, $param) {
+               $pool = $this->Pool->getDirectiveValue();
+               if (empty($pool)) {
+                       return;
+               }
+               $this->setStorageByPool($pool, 'set_storage_from_pool_cb');
+       }
+
+       /**
+        * Load selection types (step 3).
+        *
+        * @return none
+        */
+       public function loadSelectionTypes() {
+               $this->SelectionType->setData($this->sel_types);
+               $this->SelectionType->createDirective();
+       }
+
+       /**
+        * Load jobs to select one (step 3).
+        *
+        * @param TCallback $sender callback object
+        * @param TCallbackEventParameter $param callback parameter
+        * @return none
+        */
+       public function loadJobList($sender, $param) {
+               $result = $this->getModule('api')->get([
+                       'jobs',
+                       'show',
+                       '?output=json'
+               ]);
+               $jobs = [];
+               if ($result->error === 0) {
+                       for ($i = 0; $i < count($result->output); $i++) {
+                               if ($result->output[$i]->jobtype != '66') {
+                                       continue;
+                               }
+                               $jobs[] = [
+                                       'job' => $result->output[$i]->name,
+                                       'enabled' => $result->output[$i]->enabled,
+                                       'priority' => $result->output[$i]->priority,
+                                       'type' => chr($result->output[$i]->jobtype),
+                                       'maxjobs' => $result->output[$i]->maxjobs
+                               ];
+                       }
+               }
+               $this->getCallbackClient()->callClientFunction(
+                       'oJobList.init',
+                       [$jobs]
+               );
+       }
+
+       /**
+        * Load clients to select one (step 3).
+        *
+        * @param TCallback $sender callback object
+        * @param TCallbackEventParameter $param callback parameter
+        * @return none
+        */
+       public function loadClientList($sender, $param) {
+               $result = $this->getModule('api')->get(
+                       ['clients']
+               );
+               $clients = [];
+               if ($result->error === 0) {
+                       $clients = $result->output;
+               }
+               $this->getCallbackClient()->callClientFunction(
+                       'oClientList.init',
+                       [$clients]
+               );
+       }
+
+       /**
+        * Load pool list (step 4).
+        *
+        * @return none
+        */
+       public function loadNextPools() {
+               $this->setPools('NextPool', $this->NextPool);
+       }
+
+       public function setStorages($control) {
+               $storage_list = [];
+               $storages = $this->getModule('api')->get([
+                       'config',
+                       'dir',
+                       'storage'
+               ]);
+               if ($storages->error === 0) {
+                       for ($i = 0; $i < count($storages->output); $i++) {
+                               $storage_list[] = $storages->output[$i]->Storage->Name;
+                       }
+                       sort($storage_list);
+                       $control->setData($storage_list);
+                       $jobdefs = $this->getJobDefs();
+                       if (key_exists('Storage', $jobdefs) && is_array($jobdefs['Storage']) && count($jobdefs['Storage']) == 1 && is_null($control->getDirectiveValue())) {
+                               $control->setDirectiveValue($jobdefs['Storage'][0]);
+                       }
+                       $control->createDirective();
+               }
+       }
+
+       /**
+        * Load destination storage list (step 4).
+        *
+        * @return none
+        */
+       public function loadDestinationStorages() {
+               $this->setStorages($this->DestinationStorage);
+       }
+
+       /**
+        * Set storage control basing on usage in pool.
+        *
+        * @param TCallback $sender callback object
+        * @param TCallbackEventParameter $param callback parameter
+        * @return none
+        */
+       public function setStorageByPool($pool, $cb) {
+               $pool = $this->getModule('api')->get([
+                       'config',
+                       'dir',
+                       'pool',
+                       $pool
+               ]);
+               if ($pool->error === 0) {
+                       $storage = null;
+                       if (property_exists($pool->output, 'Storage') && is_array($pool->output->Storage) && count($pool->output->Storage) == 1) {
+                               $storage = $pool->output->Storage[0];
+                       }
+                       $this->getCallbackClient()->callClientFunction($cb, [$storage]);
+               }
+       }
+
+       /**
+        * Set destination storage control basing on pool configuration.
+        *
+        * @param TCallback $sender callback object
+        * @param TCallbackEventParameter $param callback parameter
+        * @return none
+        */
+       public function setDestinationStorageByPool($sender, $param) {
+               $nextpool = $this->NextPool->getDirectiveValue();
+               if (empty($nextpool)) {
+                       return;
+               }
+               $this->setStorageByPool($nextpool, 'set_storage_from_pool_cb');
+       }
+
+       /**
+        * Get jobs that use pool and send them to warning box.
+        *
+        * @param TCallback $sender callback object
+        * @param TCallbackEventParameter $param callback parameter
+        * @return none
+        */
+       public function getJobsUsingPool($sender, $param) {
+               $values = $param->getCallbackParameter();
+               $job_list = [];
+               $jobs = $this->getModule('api')->get([
+                       'config',
+                       'dir',
+                       'job',
+                       '?apply_jobdefs=1'
+               ]);
+               if ($jobs->error === 0) {
+                       for ($i = 0; $i < count($jobs->output); $i++) {
+                               if (property_exists($jobs->output[$i]->Job, 'Pool') && $jobs->output[$i]->Job->Pool == $values->pool) {
+                                       $job_list[] = $jobs->output[$i]->Job->Name;
+                               }
+                       }
+               }
+               if (count($job_list) > 0) {
+                       sort($job_list);
+                       $this->getCallbackClient()->callClientFunction('show_storage_warning', [
+                               $values->storage,
+                               $values->pool,
+                               $job_list
+                       ]);
+               }
+       }
+
+       /**
+        * Load messages (step 5).
+        *
+        * @return none
+        */
+       public function loadMessages() {
+               $message_list = [];
+               $messages = $this->getModule('api')->get([
+                       'config',
+                       'dir',
+                       'messages'
+               ]);
+               if ($messages->error === 0) {
+                       for ($i = 0; $i < count($messages->output); $i++) {
+                               $message_list[] = $messages->output[$i]->Messages->Name;
+                       }
+                       sort($message_list);
+                       $this->Messages->setData($message_list);
+                       $jobdefs = $this->getJobDefs();
+                       if (key_exists('Messages', $jobdefs)) {
+                               $this->Messages->setDirectiveValue($jobdefs['Messages']);
+                       }
+                       $this->Messages->createDirective();
+               }
+       }
+
+       /**
+        * Load schedule (step 5).
+        *
+        * @return none
+        */
+       public function loadSchedules() {
+               $schedule_list = [];
+               $schedules = $this->getModule('api')->get([
+                       'config',
+                       'dir',
+                       'schedule'
+               ]);
+               if ($schedules->error === 0) {
+                       for ($i = 0; $i < count($schedules->output); $i++) {
+                               $schedule_list[] = $schedules->output[$i]->Schedule->Name;
+                       }
+                       asort($schedule_list);
+                       $this->Schedule->setData($schedule_list);
+                       $jobdefs = $this->getJobDefs();
+                       if (key_exists('Schedule', $jobdefs)) {
+                               $this->Schedule->setDirectiveValue($jobdefs['Schedule']);
+                       }
+                       $this->Schedule->createDirective();
+               }
+       }
+
+       /**
+        * Load job levels (step 5).
+        *
+        * @return none
+        */
+       public function loadLevels() {
+               // so far backup job levels only
+               $levels = $this->getModule('misc')->getJobLevels();
+               $level_list = array_values($levels);
+               $this->Level->setData($level_list);
+               $jobdefs = $this->getJobDefs();
+               if (key_exists('Level', $jobdefs)) {
+                       $this->Level->setDirectiveValue($jobdefs['Level']);
+               } elseif (count($level_list) > 0) {
+                       // no level in jobdefs, take first level
+                       $this->Level->setDirectiveValue($level_list[0]);
+               }
+               $this->Level->createDirective();
+       }
+
+       /**
+        * Load clients (step 5).
+        *
+        * @return none
+        */
+       public function loadClients() {
+               $clients = $this->getModule('api')->get([
+                       'config',
+                       'dir',
+                       'client'
+               ]);
+               if ($clients->error === 0) {
+                       for ($i = 0; $i < count($clients->output); $i++) {
+                               $client_list[] = $clients->output[$i]->Client->Name;
+                       }
+                       sort($client_list);
+                       $this->Client->setData($client_list);
+                       $jobdefs = $this->getJobDefs();
+                       if (key_exists('Client', $jobdefs) && is_array($jobdefs['Client']) && is_null($this->Client->getDirectiveValue())) {
+                               $this->Client->setDirectiveValue($jobdefs['Client']);
+                       } elseif (count($client_list) > 0) {
+                               $this->Client->setDirectiveValue($client_list[0]);
+                       }
+                       $this->Client->createDirective();
+               }
+       }
+
+       /**
+        * Load filesets (step 5).
+        *
+        * @return none
+        */
+       public function loadFileSets() {
+               $filesets = $this->getModule('api')->get([
+                       'config',
+                       'dir',
+                       'fileset'
+               ]);
+               if ($filesets->error === 0) {
+                       for ($i = 0; $i < count($filesets->output); $i++) {
+                               $fileset_list[] = $filesets->output[$i]->Fileset->Name;
+                       }
+                       sort($fileset_list);
+                       $this->FileSet->setData($fileset_list);
+                       $jobdefs = $this->getJobDefs();
+                       if (key_exists('Fileset', $jobdefs) && is_array($jobdefs['Fileset']) && is_null($this->Fileset->getDirectiveValue())) {
+                               $this->FileSet->setDirectiveValue($jobdefs['Fileset']);
+                       } elseif (count($fileset_list) > 0) {
+                               $this->FileSet->setDirectiveValue($fileset_list[0]);
+                       }
+                       $this->FileSet->createDirective();
+               }
+       }
+
+       /**
+        * Get selection pattern control.
+        *
+        * @return DirectiveTextBox selection pattern control.
+        */
+       public function getSelectionPatternControl() {
+               $control = null;
+               $sel_type = $this->SelectionType->getDirectiveValue();
+               switch ($sel_type) {
+                       case 'Job': $control = $this->SelectionPatternJob; break;
+                       case 'Client': $control = $this->SelectionPatternClient; break;
+                       case 'Volume': $control = $this->SelectionPatternVolume; break;
+                       case 'SQLQuery': $control = $this->SelectionPatternSQLQuery; break;
+               }
+               return $control;
+       }
+
+       /**
+        * Get selection pattern value.
+        *
+        * @return string selection pattern value
+        */
+       public function getSelectionPatternValue() {
+               $sel_pattern = '';
+               $sp_control = $this->getSelectionPatternControl();
+               if (is_object($sp_control)) {
+                       $sel_pattern = $sp_control->getDirectiveValue();
+               }
+               return $sel_pattern;
+       }
+
+       public function wizardCompleted($sender, $param) {
+               $jobdefs = $this->getJobDefs();
+               $job = [
+                       'Name' => $this->Name->getDirectiveValue(),
+                       'Type' => 'Migrate',
+               ];
+               $jd = $this->JobDefs->getDirectiveValue();
+               $directives = ['Description', 'Pool', 'SourceStorage', 'Level',
+                       'SelectionType', 'MaximumSpawnedJobs', 'Schedule',
+                       'Messages', 'Client', 'FileSet', 'NextPool', 'PurgeMigrationJob'
+               ];
+               if (is_string($jd)) {
+                       $job['JobDefs'] = $jd;
+               }
+               for ($i = 0; $i < count($directives); $i++) {
+                       $val = $this->{$directives[$i]}->getDirectiveValue();
+                       if (is_null($val)) {
+                               continue;
+                       }
+                       $directive = $directives[$i];
+                       if ($directive == 'SourceStorage') {
+                               $directive = 'Storage';
+                       }
+                       if (is_null($jd) || !$this->isInJobDefs($directive, $val)) {
+                               $job[$directive] = $val;
+                       }
+               }
+
+               // selection type
+               $sel_type = $this->SelectionType->getDirectiveValue();
+               $job['SelectionType'] = $sel_type;
+
+               // selection pattern
+               $sel_pattern = $this->getSelectionPatternValue();
+               if (!empty($sel_pattern)) {
+                       $job['SelectionPattern'] = $sel_pattern;
+               }
+
+               // Add to source pool directives specific for  pool occupancy and pool time selection type
+               if ($sel_type == 'PoolOccupancy' || $sel_type == 'PoolTime') {
+                       $pool = $this->Pool->getDirectiveValue();
+                       $params = [
+                               'config',
+                               'dir',
+                               'Pool',
+                               $pool
+                       ];
+                       $result = $this->getModule('api')->get(
+                               $params
+                       );
+
+                       if ($result->error === 0) {
+                               $pool = (array)$result->output;
+                               if ($sel_type == 'PoolOccupancy') {
+                                       $pool['MigrationLowBytes'] = $this->MigrationLowBytes->getDirectiveValue();
+                                       $pool['MigrationHighBytes'] = $this->MigrationHighBytes->getDirectiveValue();
+                               } elseif ($sel_type == 'PoolTime') {
+                                       $pool['MigrationTime'] = $this->MigrationTime->getDirectiveValue();
+                               }
+
+                               $result = $this->getModule('api')->set(
+                                       $params,
+                                       ['config' => json_encode($pool)]
+                               );
+
+                               if ($result->error !== 0) {
+                                       $this->CreateResourceErrMsg->Display = 'Dynamic';
+                                       $this->CreateResourceErrMsg->Text = $result->output;
+                                       return; // END
+                               }
+                       }
+               }
+
+               // Add storage to pool
+               $nextpool = $this->NextPool->getDirectiveValue();
+               $params = [
+                       'config',
+                       'dir',
+                       'Pool',
+                       $nextpool
+               ];
+               $result = $this->getModule('api')->get(
+                       $params
+               );
+
+               $pool_modified = false;
+               if ($result->error === 0) {
+                       $pool = (array)$result->output;
+                       $pool['Storage'] = $this->DestinationStorage->getDirectiveValue();
+                       $result = $this->getModule('api')->set(
+                               $params,
+                               ['config' => json_encode($pool)]
+                       );
+                       if ($result->error === 0) {
+                               $pool_modified = true;
+                       } else {
+                               $this->CreateResourceErrMsg->Display = 'Dynamic';
+                               $this->CreateResourceErrMsg->Text = $result->output;
+                       }
+               }
+
+               // create migrate job
+               if ($pool_modified) {
+                       $params = [
+                               'config',
+                               'dir',
+                               'Job',
+                               $job['Name']
+                       ];
+                       $result = $this->getModule('api')->set(
+                               $params,
+                               ['config' => json_encode($job)]
+                       );
+                       if ($result->error === 0) {
+                               $this->getModule('api')->set(array('console'), array('reload'));
+                               $this->goToPage('JobList');
+                       } else {
+                               $this->CreateResourceErrMsg->Display = 'Dynamic';
+                               $this->CreateResourceErrMsg->Text = $result->output;
+                       }
+               }
+       }
+
+       /**
+        * Cancel wizard.
+        *
+        * @return none
+        */
+       public function wizardStop($sender, $param) {
+               $this->goToDefaultPage();
+       }
+
+       /**
+        * Set selected JobDefs values.
+        *
+        * @param $jobdefs selected JobDefs values
+        * @return none
+        */
+       public function setJobDefs($jobdefs) {
+               $this->setViewState(self::JOBDEFS, $jobdefs);
+       }
+
+       /**
+        * Get selected JobDefs values.
+        *
+        * @return array selected JobDefs values
+        */
+       public function getJobDefs() {
+               return $this->getViewState(self::JOBDEFS, array());
+       }
+
+       /**
+        * Set previous wizard step.
+        *
+        * @param integer $step previous step number
+        * @return none
+        */
+       public function setPrevStep($step) {
+               $step = intval($step);
+               $this->setViewState(self::PREV_STEP, $step);
+       }
+
+       /**
+        * Get previous wizard step.
+        *
+        * @return integer previous wizard step
+        */
+       public function getPrevStep() {
+               return $this->getViewState(self::PREV_STEP);
+       }
+}
+?>
index 51eb579fbe122c4a2c672eeed19158dc2973479c..76463225f5d28b7256b90f83b3dd2c890c63623d 100644 (file)
@@ -39,6 +39,7 @@
        <url ServiceParameter="RestoreWizard" pattern="web/restore/{jobid}/" parameters.jobid="\d+" />
        <url ServiceParameter="NewBackupJobWizard" pattern="web/new/backup-job/" />
        <url ServiceParameter="NewCopyJobWizard" pattern="web/new/copy-job/" />
+       <url ServiceParameter="NewMigrateJobWizard" pattern="web/new/migrate-job/" />
        <url ServiceParameter="BaculumError" pattern="web/message/{error}/" parameters.error="\d+" />
        <url ServiceParameter="Monitor" pattern="web/monitor/" />
        <url ServiceParameter="OAuth2Redirect" pattern="web/redirect/" />