replace storage popup with modal

This commit is contained in:
Andrew Bauer 2020-09-14 09:50:04 -05:00
parent 0a0b555c4c
commit d2bc39f65f
7 changed files with 171 additions and 123 deletions

View File

@ -31,6 +31,10 @@ switch ( $modal ) {
case 'delconfirm' :
$data['html'] = getDelConfirmHTML();
break;
case 'storage' :
if ( !isset($_REQUEST['id']) ) ajaxError('Storage Id Not Provided');
$data['html'] = getStorageModalHTML($_REQUEST['id']);
break;
default :
// Maybe don't need both
ZM\Warning('Unknown modal '.$modal);

View File

@ -24,7 +24,7 @@ if ( !canEdit('System') ) {
return;
}
if ( $action == 'Save' ) {
if ( $action == 'save' ) {
$storage = new ZM\Storage($_REQUEST['id']);
$changes = $storage->changes($_REQUEST['newStorage']);
@ -33,7 +33,7 @@ if ( $action == 'Save' ) {
$storage->save($changes);
$refreshParent = true;
}
$view = 'none';
$redirect = '?view=options&tab=storage';
} else {
ZM\Error("Unknown action $action in saving Storage");
}

View File

@ -905,6 +905,117 @@ function getDelConfirmHTML() {
return $result;
}
function getStorageModalHTML($sid) {
$result = '';
$null = '';
$checked = 'checked="checked"';
if ( !canEdit('System') ) return;
require_once('includes/Server.php');
require_once('includes/Storage.php');
if ( $_REQUEST['id'] ) {
if ( !($newStorage = ZM\Storage::find_one(array('Id'=>$sid)) ) ) {
// Perhaps do something different here, rather than return nothing
return;
}
} else {
$newStorage = new ZM\Storage();
$newStorage->Name(translate('NewStorage'));
}
$type_options = array( 'local' => translate('Local'), 's3fs' => translate('s3fs') );
$scheme_options = array(
'Deep' => translate('Deep'),
'Medium' => translate('Medium'),
'Shallow' => translate('Shallow'),
);
$servers = ZM\Server::find( null, array('order'=>'lower(Name)') );
$ServersById = array();
foreach ( $servers as $S ) {
$ServersById[$S->Id()] = $S;
}
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
if ( isset($GLOBALS['csrf']['key']) ) {
$csrf_input = '<input type="hidden" name="__csrf_magic" value="key:' .csrf_hash($GLOBALS['csrf']['key']). '" />'.PHP_EOL;
} else {
$csrf_input = '';
}
$result .= '<div class="modal fade" id="storageModal" data-backdrop="static" data-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">'.PHP_EOL;
$result .= '<div class="modal-dialog">'.PHP_EOL;
$result .= '<div class="modal-content">'.PHP_EOL;
$result .= '<div class="modal-header">'.PHP_EOL;
$result .= '<h5 class="modal-title" id="staticBackdropLabel">' .translate('Storage').' - '.$newStorage->Name(). '</h5>'.PHP_EOL;
$result .= '<button type="button" class="close" data-dismiss="modal" aria-label="Close">'.PHP_EOL;
$result .= '<span aria-hidden="true">&times;</span>'.PHP_EOL;
$result .= '</button>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '<div class="modal-body">'.PHP_EOL;
$result .= '<form id="storageModalForm" name="contentForm" method="post" action="?view=storage&action=save" class="validateFormOnSubmit">'.PHP_EOL;
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
$result .= $csrf_input;
$result .= '<input type="hidden" name="view" value="storage"/>'.PHP_EOL;
$result .= '<input type="hidden" name="object" value="storage"/>'.PHP_EOL;
$result .= '<input type="hidden" name="id" value="' .validHtmlStr($sid). '"/>'.PHP_EOL;
$result .= '<table id="contentTable" class="major">'.PHP_EOL;
$result .= '<tbody>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th class="text-right pr-3" scope="row">' .translate('Name'). '</th>'.PHP_EOL;
$result .= '<td><input type="text" name="newStorage[Name]" value="' .$newStorage->Name(). '"/></td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th class="text-right pr-3" scope="row">' .translate('Path'). '</th>'.PHP_EOL;
$result .= '<td><input type="text" name="newStorage[Path]" value="' .$newStorage->Path(). '"/></td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th class="text-right pr-3" scope="row">' .translate('Url'). '</th>'.PHP_EOL;
$result .= '<td><input type="text" name="newStorage[Url]" value="' .$newStorage->Url(). '"/></td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th class="text-right pr-3" scope="row">' .translate('Server'). '</th>'.PHP_EOL;
$result .= '<td>' .htmlSelect('newStorage[ServerId]', array(''=>'Remote / No Specific Server') + $ServersById, $newStorage->ServerId()). '</td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th class="text-right pr-3" scope="row">' .translate('Type'). '</th>'.PHP_EOL;
$result .= '<td>' .htmlSelect('newStorage[Type]', $type_options, $newStorage->Type()). '</td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th class="text-right pr-3" scope="row">' .translate('StorageScheme'). '</th>'.PHP_EOL;
$result .= '<td>' .htmlSelect('newStorage[Scheme]', $scheme_options, $newStorage->Scheme()). '</td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th class="text-right pr-3" scope="row">' .translate('StorageDoDelete'). '</th>'.PHP_EOL;
$result .= '<td>'.PHP_EOL;
$result .= '<input type="radio" name="newStorage[DoDelete]" value="1" ' .($newStorage->DoDelete() ? $checked : $null). '>Yes'.PHP_EOL;
$result .= '<input type="radio" name="newStorage[DoDelete]" value="0" ' .($newStorage->DoDelete() ? $null : $checked). '>No'.PHP_EOL;
$result .= '</td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th class="text-right pr-3" scope="row">' .translate('Enabled'). '</th>'.PHP_EOL;
$result .= '<td>'.PHP_EOL;
$result .= '<input type="radio" name="newStorage[Enabled]" value="1" ' .($newStorage->Enabled() ? $checked : $null). '>Yes'.PHP_EOL;
$result .= '<input type="radio" name="newStorage[Enabled]" value="0" ' .($newStorage->Enabled() ? $null : $checked). '>No'.PHP_EOL;
$result .= '</td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '</tbody>'.PHP_EOL;
$result .= '</table>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '<div class="modal-footer">'.PHP_EOL;
$result .= '<button name="action" id="storageSubmitBtn" type="submit" class="btn btn-primary" value="Save">' .translate('Save'). '</button>'.PHP_EOL;
$result .= '<button type="button" class="btn btn-secondary" data-dismiss="modal">' .translate('Cancel'). '</button>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</form>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
return $result;
}
function xhtmlFooter() {
global $css;
global $cspNonce;

View File

@ -0,0 +1,45 @@
// Load the Storage Modal HTML via Ajax call
function getStorageModal(sid) {
$j.getJSON(thisUrl + '?request=modal&modal=storage&id=' + sid)
.done(function(data) {
if ( $j('#storageModal').length ) {
$j('#storageModal').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
$j('#storageModal').modal('show');
// Manage the Save button
$j('#storageSubmitBtn').click(function(evt) {
evt.preventDefault();
$j('#storageModalForm').submit();
});
})
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText);
});
}
function enableStorageModal() {
$j(".storageCol").click(function(evt) {
evt.preventDefault();
var sid = $j(this).data('sid');
getStorageModal(sid);
});
$j('#NewStorageBtn').click(function(evt) {
evt.preventDefault();
getStorageModal(0);
});
}
function initPage() {
var NewStorageBtn = $j('#NewStorageBtn');
if ( canEditSystem ) enableStorageModal();
NewStorageBtn.prop('disabled', !canEditSystem);
}
$j(document).ready(function() {
initPage();
});

View File

@ -3,3 +3,5 @@ var restartWarning = <?php echo empty($restartWarning)?'false':'true' ?>;
if ( restartWarning ) {
alert( "<?php echo translate('OptionRestartWarning') ?>" );
}
var canEditSystem = <?php echo canEdit('System') ? 'true' : 'false' ?>;

View File

@ -272,12 +272,12 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*', GLOB_ONLYDIR)) as
<tbody>
<?php foreach( ZM\Storage::find( null, array('order'=>'lower(Name)') ) as $Storage ) { ?>
<tr>
<td class="colId"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Id()), $canEdit ) ?></td>
<td class="colName"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Name()), $canEdit ) ?></td>
<td class="colPath"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Path()), $canEdit ) ?></td>
<td class="colType"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Type()), $canEdit ) ?></td>
<td class="colScheme"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Scheme()), $canEdit ) ?></td>
<td class="colServer"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Server()->Name()), $canEdit ) ?></td>
<td class="colId"><?php echo makeLink('#', validHtmlStr($Storage->Id()), $canEdit, 'class="storageCol" data-sid="'.$Storage->Id().'"' ) ?></td>
<td class="colName"><?php echo makeLink('#', validHtmlStr($Storage->Name()), $canEdit, 'class="storageCol" data-sid="'.$Storage->Id().'"' ) ?></td>
<td class="colPath"><?php echo makeLink('#', validHtmlStr($Storage->Path()), $canEdit, 'class="storageCol" data-sid="'.$Storage->Id().'"' ) ?></td>
<td class="colType"><?php echo makeLink('#', validHtmlStr($Storage->Type()), $canEdit, 'class="storageCol" data-sid="'.$Storage->Id().'"' ) ?></td>
<td class="colScheme"><?php echo makeLink('#', validHtmlStr($Storage->Scheme()), $canEdit, 'class="storageCol" data-sid="'.$Storage->Id().'"' ) ?></td>
<td class="colServer"><?php echo makeLink('#', validHtmlStr($Storage->Server()->Name()), $canEdit, 'class="storageCol" data-sid="'.$Storage->Id().'"' ) ?></td>
<td class="colDiskSpace"><?php echo human_filesize($Storage->disk_used_space()) . ' of ' . human_filesize($Storage->disk_total_space()) ?></td>
<td class="ColEvents"><?php echo $Storage->EventCount().' using '.human_filesize($Storage->event_disk_space()) ?></td>
<td class="colMark"><input type="checkbox" name="markIds[]" value="<?php echo $Storage->Id() ?>" data-on-click-this="configureDeleteButton"<?php if ( $Storage->EventCount() or !$canEdit ) { ?> disabled="disabled"<?php } ?><?php echo $Storage->EventCount() ? ' title="Can\'t delete as long as there are events stored here."' : ''?>/></td>
@ -286,7 +286,7 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*', GLOB_ONLYDIR)) as
</tbody>
</table>
<div id="contentButtons">
<?php echo makePopupButton('?view=storage&id=0', 'zmStorage', 'storage', translate('AddNewStorage'), canEdit('System')); ?>
<button type="button" id="NewStorageBtn" value="<?php echo translate('AddNewStorage') ?>" disabled="disabled"><?php echo translate('AddNewStorage') ?></button>
<button type="submit" class="btn-danger" name="deleteBtn" value="Delete" disabled="disabled"><?php echo translate('Delete') ?></button>
</div>
</form>

View File

@ -1,114 +0,0 @@
<?php
//
// ZoneMinder web user view file
// Copyright (C) 2020 ZoneMinder LLC
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
if ( !canEdit('System') ) {
$view = 'error';
return;
}
require_once('includes/Server.php');
require_once('includes/Storage.php');
if ( $_REQUEST['id'] ) {
if ( !($newStorage = ZM\Storage::find_one(array('Id'=>$_REQUEST['id'])) ) ) {
$view = 'error';
return;
}
} else {
$newStorage = new ZM\Storage();
$newStorage->Name(translate('NewStorage'));
}
$type_options = array( 'local' => translate('Local'), 's3fs' => translate('s3fs') );
$scheme_options = array(
'Deep' => translate('Deep'),
'Medium' => translate('Medium'),
'Shallow' => translate('Shallow'),
);
$servers = ZM\Server::find( null, array('order'=>'lower(Name)') );
$ServersById = array();
foreach ( $servers as $S ) {
$ServersById[$S->Id()] = $S;
}
$focusWindow = true;
xhtmlHeaders(__FILE__, translate('Storage').' - '.$newStorage->Name());
?>
<body>
<div id="page">
<div id="header">
<h2><?php echo translate('Storage').' - '.$newStorage->Name() ?></h2>
</div>
<div id="content">
<form name="contentForm" method="post" action="?" class="validateFormOnSubmit">
<input type="hidden" name="view" value="<?php echo $view ?>"/>
<input type="hidden" name="object" value="storage"/>
<input type="hidden" name="id" value="<?php echo validHtmlStr($_REQUEST['id']) ?>"/>
<table id="contentTable" class="major">
<tbody>
<tr>
<th scope="row"><?php echo translate('Name') ?></th>
<td><input type="text" name="newStorage[Name]" value="<?php echo $newStorage->Name() ?>"/></td>
</tr>
<tr>
<th scope="row"><?php echo translate('Path') ?></th>
<td><input type="text" name="newStorage[Path]" value="<?php echo $newStorage->Path() ?>"/></td>
</tr>
<tr>
<th scope="row"><?php echo translate('Url') ?></th>
<td><input type="text" name="newStorage[Url]" value="<?php echo $newStorage->Url() ?>"/></td>
</tr>
<tr>
<th scope="row"><?php echo translate('Server') ?></th>
<td><?php echo htmlSelect('newStorage[ServerId]', array(''=>'Remote / No Specific Server') + $ServersById, $newStorage->ServerId()); ?></td>
</tr>
<tr>
<th scope="row"><?php echo translate('Type') ?></th>
<td><?php echo htmlSelect('newStorage[Type]', $type_options, $newStorage->Type()); ?></td>
</tr>
<tr>
<th scope="row"><?php echo translate('StorageScheme') ?></th>
<td><?php echo htmlSelect('newStorage[Scheme]', $scheme_options, $newStorage->Scheme()); ?></td>
</tr>
<tr>
<th scope="row"><?php echo translate('StorageDoDelete') ?></th>
<td>
<input type="radio" name="newStorage[DoDelete]" value="1"<?php echo $newStorage->DoDelete() ? 'checked="checked"' : '' ?>/>Yes
<input type="radio" name="newStorage[DoDelete]" value="0"<?php echo $newStorage->DoDelete() ? '' : 'checked="checked"' ?>/>No
</td>
</tr>
<tr>
<th scope="row"><?php echo translate('Enabled') ?></th>
<td>
<input type="radio" name="newStorage[Enabled]" value="1"<?php echo $newStorage->Enabled() ? 'checked="checked"' : '' ?>/>Yes
<input type="radio" name="newStorage[Enabled]" value="0"<?php echo $newStorage->Enabled() ? '' : 'checked="checked"' ?>/>No
</td>
</tr>
</tbody>
</table>
<div id="contentButtons">
<button name="action" type="submit" value="Save"><?php echo translate('Save') ?></button>
<button type="button" data-on-click="closeWindow"><?php echo translate('Cancel') ?></button>
</div>
</form>
</div>
</div>
<?php xhtmlFooter() ?>