Menu="Main:2"
Title="Pool Devices"
Tag="bullseye"
Cond="($pool_devices || $var['fsState']=='Stopped')"
---
<?PHP
/* Copyright 2005-2023, Lime Technology
 * Copyright 2012-2023, Bergware International.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version 2,
 * as published by the Free Software Foundation.
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 */
?>
<?
function makeList($list) {
  return implode(',',array_map('escapestring',$list));
}
function sharename($share) {
  return basename($share,'.cfg');
}
?>
<script>
function validate(poolname) {
  var valid = /^[a-z]([a-z0-9~._-]*[a-z_-])*$/;
  var reserved = [<?=makeList(explode(',',_var($var,'reservedNames')))?>];
  var shares = [<?=makeList(array_map('sharename',glob('boot/config/shares/*.cfg',GLOB_NOSORT)))?>];
  var pools = [<?=makeList($pools)?>];
  if (!poolname.trim()) return false;
  if (reserved.includes(poolname)) {
    swal({title:"_(Invalid pool name)_",text:"_(Do not use reserved names)_",html:true,type:'error',confirmButtonText:"_(Ok)_"});
    return false;
  } else if (shares.includes(poolname)) {
    swal({title:"_(Invalid pool name)_",text:"_(Do not use user share names)_",html:true,type:'error',confirmButtonText:"_(Ok)_"});
    return false;
  } else if (pools.includes(poolname)) {
    swal({title:"_(Invalid pool name)_",text:"_(Pool name already exists)_",html:true,type:'error',confirmButtonText:"_(Ok)_"});
    return false;
  } else if (!valid.test(poolname)) {
    swal({title:"_(Invalid pool name)_",text:"_(Use only lowercase with no special characters or leading/trailing digits)_",type:'error',html:true,confirmButtonText:"_(Ok)_"});
    return false;
  }
  return true;
}
function dialogStyle() {
  $('.ui-dialog-titlebar-close').css({'display':'none'});
  $('.ui-dialog-title').css({'text-align':'center','width':'100%','font-size':'1.8rem'});
  $('.ui-dialog-content').css({'padding-top':'15px','vertical-align':'bottom'});
  $('.ui-button-text').css({'padding':'0px 5px'});
}
function addPoolPopup() {
  var popup = $('#dialogWindow');
  // Load popup with the template info
  popup.html($("#templatePopupPool").html());
  // Start Dialog section
  popup.dialog({
    title: "_(Add Pool)_",
    height: 'auto',
    width: 600,
    resizable: false,
    modal: true,
    buttons: {
    "_(Add)_": function() {
        if (validate($(this).find('input[name="poolName"]').val())) {
          $(this).find('form').submit();
          $(this).dialog('close');
        }
      },
    "_(Cancel)_": function() {
        $(this).dialog('close');
      }
    }
  });
  dialogStyle();
}
function removeOption(inputString,value) {
  // Define a regular expression to match <option>...</option> substrings
  const optionPattern = /<option .*?<\/option>/g;
  // Replace all matching substrings that contain "value" with an empty string
  const result = inputString.replace(optionPattern, (match) => {
    if (match.includes(value)) {
      return ''; // Remove the entire substring
    } else {
      return match; // Keep the substring as is
    }
  });
  return result;
}
function addSubpoolPopup(poolname,currentsubpools) {
  var popup = $('#dialogWindow');
  // Load popup with the template info
  popup.html($("#templatePopupSubpool").html());
  // Remove the options specifed by currentsubpools
  if (currentsubpools.trim().length !== 0) {
    var subpools = currentsubpools.split(',');
    subpools.forEach(function(subpool) {
      popup.html(function(index, oldHtml) {
        return removeOption(oldHtml, subpool);
      });
    });
  }
  // Start Dialog section
  popup.dialog({
    title: "_(Add ZFS Subpool)_",
    height: 'auto',
    width: 600,
    resizable: false,
    modal: true,
    buttons: {
    "_(Add)_": function() {
        subpool=$(this).find('select[name="subpool"]').val();
        $(this).find('input[name="poolName"]').val(poolname + '<?=$_tilde_?>' + subpool);
        $(this).find('form').submit();
        $(this).dialog('close');
      },
    "_(Cancel)_": function() {
        $(this).dialog('close');
      }
    }
  });
  dialogStyle();
}

<?if (_var($var,'fsState')=="Started"):?>
$('#tab2').bind({click:function() {$('i.toggle').show('slow');}});
<?endif;?>
</script>

<?
// Check for deprecated filesystems using shared function
$deprecatedPools = check_deprecated_filesystems_array($disks, 'cache_filter');
?>


<div class="TableContainer">
<table class="unraid disk_status">
<?$i = 0?>
<?foreach ($pools as $pool):?>
<?if (isset($disks[$pool]['devices']) or _var($var,'fsState')=="Stopped"):?>
<?if (!isSubpool($pool)):
$cache = array_filter(cache_filter($disks),function($disk) use ($pool){return prefix($disk['name'])==$pool;});
$power = _var($display,'power') && in_array('nvme',array_column($cache,'transport')) ? _('Power').' / ' : '';
$root  = explode($_tilde_,$pool)[0];
?>
<?if ($i==0):?>
<thead>
  <tr>
    <td>_(Device)_</td>
    <td>_(Identification)_</td>
    <td><?=$power?>_(Temp)_</td>
    <td>_(Reads)_</td>
    <td>_(Writes)_</td>
    <td>_(Errors)_</td>
    <td>_(FS)_</td>
    <td>_(Size)_</td>
    <td>_(Used)_</td>
    <td>_(Free)_</td>
  </tr>
</thead>
<?else:?>
<thead>
  <tr>
    <td class="divider" colspan="10"></td>
  </tr>
</thead>
<?endif;?>
<?endif;?>
<tbody id="pool_device<?=$i++?>">
<?foreach ($cache as $disk) if (substr($disk['status'],0,7)!='DISK_NP') echo "<tr><td colspan='10'></td></tr>"?>
<?if (_var($display,'total') && _var($cache[$root],'devices',0)>1) echo "<tr class='tr_last'><td colspan='10'></td></tr>"?>
</tbody>
<?endif;?>
<?endforeach;?>
</table>
</div>

<?=display_deprecated_filesystem_warning($deprecatedPools, 'pool')?>

:cache_devices_help:

<?if (_var($var,'fsState')=="Stopped"):?>
<div></div>
:cache_slots_help:
<?endif;?>

<div id="dialogWindow" class="template"></div>

<?if (_var($var,'fsState')=="Stopped"):?>
<input type="button" value="_(Add Pool)_" style="margin:0" onclick="addPoolPopup()">

<div id="templatePopupPool" class="template">
<form markdown="1" method="POST" action="/update.htm" target="progressFrame" onsubmit="return validate(this.poolName.value)">
<input type="hidden" name="changeSlots" value="apply">

_(Name)_:
: <input type="text" name="poolName" maxlength="40" value="<?=count($pools)==0?'cache':''?>">

_(Slots)_:
: <select name="poolSlots">
  <?for ($n=1; $n<=_var($var,'MAX_CACHESZ',0); $n++):?>
  <?=mk_option(1,$n,$n)?>
  <?endfor;?>
  </select>

</form>
</div>

<div id="templatePopupSubpool" class="template">
<form markdown="1" method="POST" action="/update.htm" target="progressFrame">
<input type="hidden" name="changeSlots" value="apply">
<input type="hidden" name="poolName" value="">

_(Name)_:
: <select name="subpool">
  <?=mk_option("","special",_("special - Metadata storage"))?>
  <?=mk_option("","logs",_("logs - Separate Intent Log (SLOG)"))?>
  <?=mk_option("","dedup",_("dedup - Deduplication Tables"))?>
  <?=mk_option("","cache",_("cache - L2ARC"))?>
  <?=mk_option("","spares",_("spares - Hot Spares"),'disabled')?>
  </select>

_(Slots)_:
: <select name="poolSlots">
  <?for ($n=1; $n<=_var($var,'MAX_CACHESZ',0); $n++):?>
  <?=mk_option(1,$n,$n)?>
  <?endfor;?>
  </select>

</form>
</div>
<?endif;?>
