UI overhaul (#383)
This commit is contained in:
@@ -2,91 +2,130 @@
|
||||
<h1 id="gametitle_label">About Gaseous</h1>
|
||||
</div>
|
||||
|
||||
<table style="width: 100%;">
|
||||
<tr>
|
||||
<th style="width: 20%;">Home Page</th>
|
||||
<td><a href="https://github.com/gaseous-project/gaseous-server" class="romlink">https://github.com/gaseous-project/gaseous-server</a></td>
|
||||
<td rowspan="5" style="text-align: center; width: 128px;">
|
||||
<img src="/images/logo.png" style="display: block; margin: 20px auto; width: 100px;" />
|
||||
<span style="display: block;">The Gaseous logo was designed by Tom2.0</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Bugs and Feature Requests</th>
|
||||
<td><a href="https://github.com/gaseous-project/gaseous-server/issues" class="romlink">https://github.com/gaseous-project/gaseous-server/issues</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Join our Discord</th>
|
||||
<td><a href="https://discord.gg/Nhu7wpT3k4" class="romlink">https://discord.gg/Nhu7wpT3k4</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Server Version</th>
|
||||
<td id="settings_appversion"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Database Schema Version</th>
|
||||
<td id="settings_dbversion"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h3>Projects That Make Gaseous Possible</h3>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;"><a href="https://github.com/EmulatorJS/EmulatorJS" target="_blank"><img src="/images/EmulatorJS.png" style="height: 36px;" /></a></td>
|
||||
<td colspan="3">
|
||||
The EmulatorJS Project<br />
|
||||
<a href="https://github.com/EmulatorJS/EmulatorJS" target="_blank" class="romlink">https://github.com/EmulatorJS/EmulatorJS</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h3>Data Sources</h2>
|
||||
<h4>Game data</h4>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a href="https://www.igdb.com/" target="_blank"><img src="/images/IGDB_logo.svg" style="filter: invert(100%); height: 36px;" /></a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
The Internet Game Database<br />
|
||||
<a href="https://www.igdb.com/" target="_blank" class="romlink">https://www.igdb.com/</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h4>Signature data sources</h4>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a href="https://www.tosecdev.org/" target="_blank"><img src="/images/TOSEC_logo.gif" style="height: 36px;" /></a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
The Old School Emulation Center<br />
|
||||
<a href="https://www.tosecdev.org/" target="_blank" class="romlink">https://www.tosecdev.org/</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a href="https://www.progettosnaps.net/index.php" target="_blank"><img src="/images/ProgettoSnaps.gif" style="height: 36px;" /></a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
Progetto-Snaps<br />
|
||||
<a href="https://www.progettosnaps.net/index.php" target="_blank" class="romlink">https://www.progettosnaps.net/index.php</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="section">
|
||||
<div class="section-body">
|
||||
<table style="width: 100%;">
|
||||
<tr>
|
||||
<td style="width: 20%;">Home Page</td>
|
||||
<td><a href="https://github.com/gaseous-project/gaseous-server" class="romlink" target="_blank"
|
||||
rel="noopener noreferrer">https://github.com/gaseous-project/gaseous-server</a></td>
|
||||
<td rowspan="5" style="text-align: center; width: 128px;">
|
||||
<img src="/images/logo.png" style="display: block; margin: 20px auto; width: 100px;" />
|
||||
<span style="display: block;">The Gaseous logo was designed by Tom1243</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Bugs and Feature Requests</td>
|
||||
<td><a href="https://github.com/gaseous-project/gaseous-server/issues" class="romlink" target="_blank"
|
||||
rel="noopener noreferrer">https://github.com/gaseous-project/gaseous-server/issues</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Join our Discord</td>
|
||||
<td><a href="https://discord.gg/Nhu7wpT3k4" class="romlink" target="_blank"
|
||||
rel="noopener noreferrer">https://discord.gg/Nhu7wpT3k4</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Server Version</td>
|
||||
<td id="settings_appversion"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Database Schema Version</td>
|
||||
<td id="settings_dbversion"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="section-header">Projects That Make Gaseous Possible</div>
|
||||
<div class="section-body">
|
||||
<table style="width: 100%;">
|
||||
<tr>
|
||||
<td style="text-align: center; width: 20%;"><a href="https://github.com/EmulatorJS/EmulatorJS"
|
||||
target="_blank" rel="noopener noreferrer"><img src="/images/EmulatorJS.png"
|
||||
style="height: 36px;" /></a></td>
|
||||
<td colspan="3">
|
||||
The EmulatorJS Project<br />
|
||||
<a href="https://github.com/EmulatorJS/EmulatorJS" class="romlink" target="_blank"
|
||||
rel="noopener noreferrer">https://github.com/EmulatorJS/EmulatorJS</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="section-header">Data Sources</div>
|
||||
<div class="section-body">
|
||||
<table style="width: 100%;">
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h4>Metadata sources</h4>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center; width: 20%;">
|
||||
<a href="https://www.igdb.com/" target="_blank" rel="noopener noreferrer"><img
|
||||
src="/images/IGDB_logo.svg" style="filter: invert(100%); height: 36px;" /></a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
The Internet Game Database<br />
|
||||
<a href="https://www.igdb.com/" target="_blank" rel="noopener noreferrer"
|
||||
class="romlink">https://www.igdb.com/</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h4>Signature data sources</h4>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a href="https://hasheous.org/" target="_blank" rel="noopener noreferrer"><img
|
||||
src="/images/hasheous.svg" style="height: 36px;" /></a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
Hasheous<br />
|
||||
<a href="https://hasheous.org/" target="_blank" rel="noopener noreferrer"
|
||||
class="romlink">https://hasheous.org/</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a href="https://www.tosecdev.org/" target="_blank" rel="noopener noreferrer"><img
|
||||
src="/images/TOSEC_logo.gif" style="height: 36px;" /></a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
The Old School Emulation Center<br />
|
||||
<a href="https://www.tosecdev.org/" target="_blank" rel="noopener noreferrer"
|
||||
class="romlink">https://www.tosecdev.org/</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a href="https://www.progettosnaps.net/index.php" target="_blank" rel="noopener noreferrer"><img
|
||||
src="/images/ProgettoSnaps.gif" style="height: 36px;" /></a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
Progetto-Snaps<br />
|
||||
<a href="https://www.progettosnaps.net/index.php" target="_blank" rel="noopener noreferrer"
|
||||
class="romlink">https://www.progettosnaps.net/index.php</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a href="https://no-intro.org" target="_blank" rel="noopener noreferrer"><img
|
||||
src="/images/NoIntro-logo.svg" style="height: 36px;" /></a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
No-Intro<br />
|
||||
<a href="https://no-intro.org" target="_blank" rel="noopener noreferrer"
|
||||
class="romlink">https://no-intro.org</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var versionBox = document.getElementById('settings_appversion');
|
||||
if (AppVersion == "1.5.0.0") {
|
||||
versionBox.innerHTML = "Built from source";
|
||||
} else {
|
||||
versionBox.innerHTML = AppVersion;
|
||||
}
|
||||
|
||||
var versionBox = document.getElementById('settings_dbversion');
|
||||
versionBox.innerHTML = DBSchemaVersion;
|
||||
// populate the page with the server version and database schema version
|
||||
populatePage();
|
||||
</script>
|
11
gaseous-server/wwwroot/pages/settings/about.js
Normal file
11
gaseous-server/wwwroot/pages/settings/about.js
Normal file
@@ -0,0 +1,11 @@
|
||||
function populatePage() {
|
||||
let appVersionBox = document.getElementById('settings_appversion');
|
||||
if (AppVersion == "1.5.0.0") {
|
||||
appVersionBox.innerHTML = "Built from source";
|
||||
} else {
|
||||
appVersionBox.innerHTML = AppVersion;
|
||||
}
|
||||
|
||||
let dbVersionBox = document.getElementById('settings_dbversion');
|
||||
dbVersionBox.innerHTML = DBSchemaVersion;
|
||||
}
|
@@ -2,121 +2,26 @@
|
||||
<h1 id="gametitle_label">Firmware</h1>
|
||||
</div>
|
||||
|
||||
<h3>Firmware Availablility <span id="firmware_totalcount" style="float: right;"></span></h3>
|
||||
<p>
|
||||
Display:
|
||||
<ul style="list-style-type:none;">
|
||||
<li><input type="checkbox" id="firmware_showavailable" checked="checked" onclick="displayFirmwareList();"/><label for="firmware_showavailable"> Available</label></li>
|
||||
<li><input type="checkbox" id="firmware_showunavailable" checked="checked" onclick="displayFirmwareList();"/><label for="firmware_showunavailable"> Unavailable</label></li>
|
||||
</ul>
|
||||
</p>
|
||||
<table id="table_firmware" class="romtable" cellspacing="0">
|
||||
<div class="section">
|
||||
<div class="section-header">Firmware Availablility <span id="firmware_totalcount" style="float: right;"></span>
|
||||
</div>
|
||||
<div class="section-body">
|
||||
<p>
|
||||
Display:
|
||||
<ul style="list-style-type:none;">
|
||||
<li><input type="checkbox" id="firmware_showavailable" checked="checked"
|
||||
onclick="displayFirmwareList();" /><label for="firmware_showavailable"> Available</label></li>
|
||||
<li><input type="checkbox" id="firmware_showunavailable" checked="checked"
|
||||
onclick="displayFirmwareList();" /><label for="firmware_showunavailable"> Unavailable</label></li>
|
||||
</ul>
|
||||
</p>
|
||||
<table id="table_firmware" class="romtable" cellspacing="0">
|
||||
|
||||
</table>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var biosDict = {};
|
||||
|
||||
ajaxCall('/api/v1.1/Bios', 'GET', function (result) {
|
||||
result.sort((a, b) => a.platformname.charCodeAt(0) - b.platformname.charCodeAt(0));
|
||||
|
||||
// sort into a dictionary
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
var tempArray = [];
|
||||
if (biosDict.hasOwnProperty(result[i].platformname)) {
|
||||
tempArray = biosDict[result[i].platformname];
|
||||
tempArray.push(result[i]);
|
||||
} else {
|
||||
tempArray.push(result[i]);
|
||||
biosDict[result[i].platformname] = tempArray;
|
||||
}
|
||||
|
||||
biosDict[result[i].platformname] = tempArray;
|
||||
}
|
||||
console.log(biosDict);
|
||||
|
||||
displayFirmwareList();
|
||||
});
|
||||
|
||||
function displayFirmwareList() {
|
||||
var lastPlatform = '';
|
||||
|
||||
var newTable = document.getElementById('table_firmware');
|
||||
newTable.innerHTML = '';
|
||||
newTable.appendChild(createTableRow(true, ['Description', 'File name', 'MD5 Hash', 'Available']));
|
||||
|
||||
var totalAvailable = 0;
|
||||
var totalCount = 0;
|
||||
|
||||
for (const [key, value] of Object.entries(biosDict)) {
|
||||
// new platform - show a header
|
||||
var platformRow = document.createElement('tr');
|
||||
var platformHeader = document.createElement('th');
|
||||
platformHeader.setAttribute('colspan', 4);
|
||||
|
||||
var platformHeaderValue = document.createElement('span');
|
||||
platformHeaderValue.innerHTML = key;
|
||||
platformHeader.appendChild(platformHeaderValue);
|
||||
|
||||
var platformHeaderCounter = document.createElement('span');
|
||||
platformHeaderCounter.style.float = 'right';
|
||||
platformHeader.appendChild(platformHeaderCounter);
|
||||
|
||||
platformRow.appendChild(platformHeader);
|
||||
newTable.appendChild(platformRow);
|
||||
|
||||
var totalPlatformAvailable = 0;
|
||||
|
||||
var showAvailable = document.getElementById('firmware_showavailable').checked;
|
||||
var showUnavailable = document.getElementById('firmware_showunavailable').checked;
|
||||
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
// update counters
|
||||
if (value[i].available == true) {
|
||||
totalAvailable += 1;
|
||||
totalPlatformAvailable += 1;
|
||||
}
|
||||
|
||||
if (
|
||||
(value[i].available == true && showAvailable == true) ||
|
||||
(value[i].available == false && showUnavailable == true)
|
||||
) {
|
||||
var biosFilename = document.createElement('a');
|
||||
biosFilename.href = '/api/v1.1/Bios/' + value[i].platformid + '/' + value[i].filename;
|
||||
biosFilename.innerHTML = value[i].filename;
|
||||
biosFilename.className = 'romlink';
|
||||
|
||||
var availableText = document.createElement('span');
|
||||
if (value[i].available == true) {
|
||||
availableText.innerHTML = 'Available';
|
||||
availableText.className = 'greentext';
|
||||
|
||||
biosFilename = document.createElement('a');
|
||||
biosFilename.href = '/api/v1.1/Bios/' + value[i].platformid + '/' + value[i].filename;
|
||||
biosFilename.innerHTML = value[i].filename;
|
||||
biosFilename.className = 'romlink';
|
||||
} else {
|
||||
availableText.innerHTML = 'Unavailable';
|
||||
availableText.className = 'redtext';
|
||||
|
||||
biosFilename = document.createElement('span');
|
||||
biosFilename.innerHTML = value[i].filename;
|
||||
}
|
||||
|
||||
var newRow = [
|
||||
value[i].description,
|
||||
biosFilename,
|
||||
value[i].hash,
|
||||
availableText
|
||||
];
|
||||
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
||||
}
|
||||
totalCount += 1;
|
||||
}
|
||||
|
||||
platformHeaderCounter.innerHTML = totalPlatformAvailable + ' / ' + value.length + ' available';
|
||||
}
|
||||
|
||||
document.getElementById('firmware_totalcount').innerHTML = totalAvailable + ' / ' + totalCount + ' available';
|
||||
}
|
||||
// load the bios list
|
||||
loadBios();
|
||||
</script>
|
303
gaseous-server/wwwroot/pages/settings/bios.js
Normal file
303
gaseous-server/wwwroot/pages/settings/bios.js
Normal file
@@ -0,0 +1,303 @@
|
||||
let biosDict = {};
|
||||
|
||||
function loadBios() {
|
||||
biosDict = {};
|
||||
|
||||
ajaxCall('/api/v1.1/Bios', 'GET', function (result) {
|
||||
result.sort((a, b) => a.platformname.charCodeAt(0) - b.platformname.charCodeAt(0));
|
||||
|
||||
// sort into a dictionary
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
let tempArray = [];
|
||||
if (biosDict.hasOwnProperty(result[i].platformname)) {
|
||||
tempArray = biosDict[result[i].platformname];
|
||||
tempArray.push(result[i]);
|
||||
} else {
|
||||
tempArray.push(result[i]);
|
||||
biosDict[result[i].platformname] = tempArray;
|
||||
}
|
||||
|
||||
biosDict[result[i].platformname] = tempArray;
|
||||
}
|
||||
|
||||
displayFirmwareList();
|
||||
});
|
||||
}
|
||||
|
||||
function displayFirmwareList() {
|
||||
let lastPlatform = '';
|
||||
|
||||
let targetDiv = document.getElementById('table_firmware');
|
||||
targetDiv.innerHTML = '';
|
||||
|
||||
let totalAvailable = 0;
|
||||
let totalCount = 0;
|
||||
|
||||
for (const [key, value] of Object.entries(biosDict)) {
|
||||
// new platform - show a header
|
||||
let platformRow = document.createElement('div');
|
||||
platformRow.classList.add('section')
|
||||
|
||||
let platformHeader = document.createElement('div');
|
||||
platformHeader.classList.add('section-header');
|
||||
|
||||
let platformHeaderValue = document.createElement('span');
|
||||
platformHeaderValue.innerHTML = key;
|
||||
platformHeader.appendChild(platformHeaderValue);
|
||||
|
||||
let platformHeaderEdit = document.createElement('a');
|
||||
platformHeaderEdit.href = '#';
|
||||
platformHeaderEdit.style.float = 'right';
|
||||
platformHeaderEdit.onclick = function () {
|
||||
let biosEditor = new BiosEditor(value[0].platformid, loadBios);
|
||||
biosEditor.open();
|
||||
};
|
||||
let platformHeaderEditIcon = document.createElement('img');
|
||||
platformHeaderEditIcon.src = '/images/edit.svg';
|
||||
platformHeaderEditIcon.classList.add('banner_button_image');
|
||||
platformHeaderEdit.appendChild(platformHeaderEditIcon);
|
||||
platformHeader.appendChild(platformHeaderEdit);
|
||||
|
||||
let platformHeaderCounter = document.createElement('span');
|
||||
platformHeaderCounter.style.float = 'right';
|
||||
platformHeaderCounter.style.marginRight = '10px';
|
||||
platformHeader.appendChild(platformHeaderCounter);
|
||||
|
||||
platformRow.appendChild(platformHeader);
|
||||
|
||||
let platformBody = document.createElement('div');
|
||||
platformBody.classList.add('section-body');
|
||||
|
||||
// create new table
|
||||
let newTable = document.createElement('table');
|
||||
newTable.classList.add('romtable');
|
||||
newTable.setAttribute('cellspacing', 0);
|
||||
|
||||
newTable.appendChild(createTableRow(true, ['Description', 'File name', 'MD5 Hash', 'Available']));
|
||||
|
||||
let totalPlatformAvailable = 0;
|
||||
|
||||
let showAvailable = document.getElementById('firmware_showavailable').checked;
|
||||
let showUnavailable = document.getElementById('firmware_showunavailable').checked;
|
||||
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
// update counters
|
||||
if (value[i].available == true) {
|
||||
totalAvailable += 1;
|
||||
totalPlatformAvailable += 1;
|
||||
}
|
||||
|
||||
if (
|
||||
(value[i].available == true && showAvailable == true) ||
|
||||
(value[i].available == false && showUnavailable == true)
|
||||
) {
|
||||
let biosFilename = document.createElement('a');
|
||||
biosFilename.href = '/api/v1.1/Bios/' + value[i].platformid + '/' + value[i].filename;
|
||||
biosFilename.innerHTML = value[i].filename;
|
||||
biosFilename.className = 'romlink';
|
||||
|
||||
let availableText = document.createElement('span');
|
||||
if (value[i].available == true) {
|
||||
availableText.innerHTML = 'Available';
|
||||
availableText.className = 'greentext';
|
||||
|
||||
biosFilename = document.createElement('a');
|
||||
biosFilename.href = '/api/v1.1/Bios/' + value[i].platformid + '/' + value[i].filename;
|
||||
biosFilename.innerHTML = value[i].filename;
|
||||
biosFilename.className = 'romlink';
|
||||
} else {
|
||||
availableText.innerHTML = 'Unavailable';
|
||||
availableText.className = 'redtext';
|
||||
|
||||
biosFilename = document.createElement('span');
|
||||
biosFilename.innerHTML = value[i].filename;
|
||||
}
|
||||
|
||||
let newRow = [
|
||||
value[i].description,
|
||||
biosFilename,
|
||||
value[i].hash,
|
||||
availableText
|
||||
];
|
||||
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell bioscell'));
|
||||
}
|
||||
totalCount += 1;
|
||||
}
|
||||
|
||||
platformHeaderCounter.innerHTML = totalPlatformAvailable + ' / ' + value.length + ' available';
|
||||
|
||||
platformBody.append(newTable);
|
||||
platformRow.append(platformBody);
|
||||
|
||||
targetDiv.append(platformRow);
|
||||
}
|
||||
|
||||
document.getElementById('firmware_totalcount').innerHTML = totalAvailable + ' / ' + totalCount + ' available';
|
||||
}
|
||||
|
||||
class BiosEditor {
|
||||
constructor(PlatformId, OKCallback, CancelCallback) {
|
||||
this.PlatformId = PlatformId;
|
||||
this.OKCallback = OKCallback;
|
||||
this.CancelCallback = CancelCallback;
|
||||
}
|
||||
|
||||
BiosItems = [];
|
||||
|
||||
async open() {
|
||||
// Create the modal
|
||||
this.dialog = await new Modal("bios");
|
||||
await this.dialog.BuildModal();
|
||||
|
||||
// Get the platform data
|
||||
await fetch('/api/v1.1/PlatformMaps/' + this.PlatformId, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then(async response => {
|
||||
if (response.ok) {
|
||||
let result = await response.json();
|
||||
this.PlatformData = result;
|
||||
|
||||
// setup the dialog
|
||||
this.dialog.modalElement.querySelector('#modal-header-text').innerHTML = this.PlatformData.igdbName;
|
||||
|
||||
// setup the bios editor page
|
||||
let biosEditor = this.dialog.modalElement.querySelector('#bios_editor');
|
||||
biosEditor.innerHTML = '';
|
||||
|
||||
for (let i = 0; i < this.PlatformData.bios.length; i++) {
|
||||
let biosItem = new MappingBiosItem(this.PlatformData.bios[i].hash, this.PlatformData.bios[i].description, this.PlatformData.bios[i].filename);
|
||||
biosEditor.appendChild(biosItem.Item);
|
||||
this.BiosItems.push(biosItem);
|
||||
}
|
||||
|
||||
let newBiosItem = new MappingBiosItem('', '', '');
|
||||
biosEditor.appendChild(newBiosItem.Item);
|
||||
this.BiosItems.push(newBiosItem);
|
||||
|
||||
let addBiosButton = this.dialog.modalElement.querySelector('#mapping_edit_bios_add');
|
||||
addBiosButton.addEventListener('click', () => {
|
||||
let newBiosItem = new MappingBiosItem('', '', '');
|
||||
biosEditor.appendChild(newBiosItem.Item);
|
||||
this.BiosItems.push(newBiosItem);
|
||||
});
|
||||
|
||||
// setup the buttons
|
||||
let okButton = new ModalButton("OK", 1, this, async function (callingObject) {
|
||||
// build bios items list
|
||||
let biosItems = [];
|
||||
for (let i = 0; i < callingObject.BiosItems.length; i++) {
|
||||
// only add items that are not deleted and have a hash and filename
|
||||
if (callingObject.BiosItems[i].Deleted == false && callingObject.BiosItems[i].HashInput.value != '' && callingObject.BiosItems[i].FilenameInput.value != '') {
|
||||
let biosItem = {
|
||||
hash: callingObject.BiosItems[i].HashInput.value,
|
||||
description: callingObject.BiosItems[i].DescriptionInput.value,
|
||||
filename: callingObject.BiosItems[i].FilenameInput.value
|
||||
};
|
||||
|
||||
biosItems.push(biosItem);
|
||||
}
|
||||
}
|
||||
callingObject.PlatformData.bios = biosItems;
|
||||
|
||||
await fetch('/api/v1.1/PlatformMaps/' + callingObject.PlatformId, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(callingObject.PlatformData)
|
||||
}).then(async response => {
|
||||
if (response.ok) {
|
||||
let result = await response.json();
|
||||
console.log(result);
|
||||
|
||||
if (callingObject.OKCallback) {
|
||||
callingObject.OKCallback();
|
||||
}
|
||||
|
||||
callingObject.dialog.close();
|
||||
} else {
|
||||
let warningDialog = new Dialog("Error", "Failed to save platform data", "OK");
|
||||
warningDialog.open();
|
||||
}
|
||||
});
|
||||
});
|
||||
this.dialog.addButton(okButton);
|
||||
|
||||
// create the cancel button
|
||||
let cancelButton = new ModalButton("Cancel", 0, this, function (callingObject) {
|
||||
if (callingObject.CancelCallback) {
|
||||
callingObject.CancelCallback();
|
||||
}
|
||||
|
||||
callingObject.dialog.close();
|
||||
});
|
||||
this.dialog.addButton(cancelButton);
|
||||
|
||||
// Show the modal
|
||||
this.dialog.open();
|
||||
} else {
|
||||
let warningDialog = new MessageBox("Error", "Failed to load platform data", "OK");
|
||||
warningDialog.open();
|
||||
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class MappingBiosItem {
|
||||
constructor(Hash, Description, Filename) {
|
||||
this.Hash = Hash;
|
||||
this.Description = Description;
|
||||
this.Filename = Filename;
|
||||
|
||||
this.Deleted = false;
|
||||
|
||||
this.Item = document.createElement('div');
|
||||
this.Item.classList.add('biositem');
|
||||
this.Item.classList.add('romrow');
|
||||
|
||||
this.HashInput = document.createElement('input');
|
||||
this.HashInput.type = 'text';
|
||||
this.HashInput.value = this.Hash;
|
||||
this.HashInput.classList.add('biosinput');
|
||||
this.HashInput.classList.add('bioshash');
|
||||
this.HashInput.placeholder = 'Hash';
|
||||
this.Item.appendChild(this.HashInput);
|
||||
|
||||
this.DescriptionInput = document.createElement('input');
|
||||
this.DescriptionInput.type = 'text';
|
||||
this.DescriptionInput.value = this.Description;
|
||||
this.DescriptionInput.classList.add('biosinput');
|
||||
this.DescriptionInput.classList.add('biosdescription');
|
||||
this.DescriptionInput.placeholder = 'Description';
|
||||
this.Item.appendChild(this.DescriptionInput);
|
||||
|
||||
this.FilenameInput = document.createElement('input');
|
||||
this.FilenameInput.type = 'text';
|
||||
this.FilenameInput.value = this.Filename;
|
||||
this.FilenameInput.classList.add('biosinput');
|
||||
this.FilenameInput.classList.add('biosfilename');
|
||||
this.FilenameInput.placeholder = 'Filename';
|
||||
this.Item.appendChild(this.FilenameInput);
|
||||
|
||||
this.DeleteButton = document.createElement('a');
|
||||
this.DeleteButton.href = '#';
|
||||
this.DeleteButton.classList.add('biositemcontrol');
|
||||
this.DeleteButton.classList.add('biosdelete');
|
||||
this.DeleteButton.addEventListener('click', () => {
|
||||
this.Item.parentElement.removeChild(this.Item);
|
||||
this.Deleted = true;
|
||||
});
|
||||
this.DeleteImage = document.createElement('img');
|
||||
this.DeleteImage.src = '/images/delete.svg';
|
||||
this.DeleteImage.alt = 'Delete';
|
||||
this.DeleteImage.title = 'Delete';
|
||||
this.DeleteImage.classList.add('banner_button_image');
|
||||
this.DeleteButton.appendChild(this.DeleteImage);
|
||||
this.Item.appendChild(this.DeleteButton);
|
||||
}
|
||||
}
|
@@ -2,62 +2,18 @@
|
||||
<h1 id="gametitle_label">Libraries</h1>
|
||||
</div>
|
||||
|
||||
<table id="settings_libraries" class="romtable" style="width: 100%;" cellspacing="0">
|
||||
<div class="section">
|
||||
<div class="section-body">
|
||||
<table id="settings_libraries" class="romtable" style="width: 100%;" cellspacing="0">
|
||||
|
||||
</table>
|
||||
<div style="text-align: right;"><button id="settings_newlibrary" onclick="showDialog('librarynew');">New
|
||||
Library</button></div>
|
||||
</table>
|
||||
<div style="text-align: right;"><button id="settings_newlibrary">New
|
||||
Library</button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function drawLibrary() {
|
||||
ajaxCall(
|
||||
'/api/v1.1/Library',
|
||||
'GET',
|
||||
function (result) {
|
||||
var newTable = document.getElementById('settings_libraries');
|
||||
newTable.innerHTML = '';
|
||||
newTable.appendChild(createTableRow(true, ['Name', 'Path', 'Default Platform', 'Default Library', '']));
|
||||
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
var platformName = '';
|
||||
if (result[i].defaultPlatformId == 0) {
|
||||
if (result[i].isDefaultLibrary == true) {
|
||||
platformName = "n/a";
|
||||
} else {
|
||||
platformName = "";
|
||||
}
|
||||
} else {
|
||||
platformName = result[i].defaultPlatformName;
|
||||
}
|
||||
|
||||
var defaultLibrary = '';
|
||||
if (result[i].isDefaultLibrary == true) {
|
||||
defaultLibrary = "Yes";
|
||||
} else {
|
||||
defaultLibrary = "";
|
||||
}
|
||||
|
||||
var deleteButton = '';
|
||||
if (result[i].isDefaultLibrary == false) {
|
||||
var deleteButton = '<a href="#" onclick="showSubDialog(\'librarydelete\', ' + result[i].id + ');" class="romlink"><img src="/images/delete.svg" class="banner_button_image" alt="Delete" title="Delete" /></a>';
|
||||
}
|
||||
|
||||
newTable.appendChild(createTableRow(
|
||||
false,
|
||||
[
|
||||
result[i].name,
|
||||
result[i].path,
|
||||
platformName,
|
||||
defaultLibrary,
|
||||
'<div style="text-align: right;">' + deleteButton + '</div>'
|
||||
],
|
||||
'romrow',
|
||||
'romcell'
|
||||
));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Load the libraries
|
||||
setupButtons();
|
||||
drawLibrary();
|
||||
</script>
|
91
gaseous-server/wwwroot/pages/settings/libraries.js
Normal file
91
gaseous-server/wwwroot/pages/settings/libraries.js
Normal file
@@ -0,0 +1,91 @@
|
||||
function setupButtons() {
|
||||
document.getElementById('settings_newlibrary').addEventListener('click', function () {
|
||||
let newLibrary = new NewLibrary();
|
||||
newLibrary.open();
|
||||
});
|
||||
}
|
||||
|
||||
function drawLibrary() {
|
||||
ajaxCall(
|
||||
'/api/v1.1/Library',
|
||||
'GET',
|
||||
function (result) {
|
||||
let newTable = document.getElementById('settings_libraries');
|
||||
newTable.innerHTML = '';
|
||||
newTable.appendChild(createTableRow(true, ['Name', 'Path', 'Default Platform', 'Default Library', '']));
|
||||
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
let platformName = '';
|
||||
if (result[i].defaultPlatformId == 0) {
|
||||
if (result[i].isDefaultLibrary == true) {
|
||||
platformName = "n/a";
|
||||
} else {
|
||||
platformName = "";
|
||||
}
|
||||
} else {
|
||||
platformName = result[i].defaultPlatformName;
|
||||
}
|
||||
|
||||
let defaultLibrary = '';
|
||||
if (result[i].isDefaultLibrary == true) {
|
||||
defaultLibrary = "Yes";
|
||||
} else {
|
||||
defaultLibrary = "";
|
||||
}
|
||||
|
||||
let controls = document.createElement('div');
|
||||
controls.style.textAlign = 'right';
|
||||
|
||||
let deleteButton = '';
|
||||
if (result[i].isDefaultLibrary == false) {
|
||||
deleteButton = document.createElement('a');
|
||||
deleteButton.href = '#';
|
||||
deleteButton.addEventListener('click', () => {
|
||||
let deleteLibrary = new MessageBox('Delete Library', 'Are you sure you want to delete this library?<br /><br /><strong>Warning</strong>: This cannot be undone!');
|
||||
deleteLibrary.addButton(new ModalButton('OK', 2, deleteLibrary, function (callingObject) {
|
||||
ajaxCall(
|
||||
'/api/v1.1/Library/' + result[i].id,
|
||||
'DELETE',
|
||||
function () {
|
||||
callingObject.msgDialog.close();
|
||||
drawLibrary();
|
||||
},
|
||||
function () {
|
||||
callingObject.msgDialog.close();
|
||||
drawLibrary();
|
||||
}
|
||||
);
|
||||
}));
|
||||
|
||||
deleteLibrary.addButton(new ModalButton('Cancel', 0, deleteLibrary, function (callingObject) {
|
||||
callingObject.msgDialog.close();
|
||||
}));
|
||||
|
||||
deleteLibrary.open();
|
||||
});
|
||||
let deleteButtonImage = document.createElement('img');
|
||||
deleteButtonImage.src = '/images/delete.svg';
|
||||
deleteButtonImage.className = 'banner_button_image';
|
||||
deleteButtonImage.alt = 'Delete';
|
||||
deleteButtonImage.title = 'Delete';
|
||||
deleteButton.appendChild(deleteButtonImage);
|
||||
|
||||
controls.appendChild(deleteButton);
|
||||
}
|
||||
|
||||
newTable.appendChild(createTableRow(
|
||||
false,
|
||||
[
|
||||
result[i].name,
|
||||
result[i].path,
|
||||
platformName,
|
||||
defaultLibrary,
|
||||
controls
|
||||
],
|
||||
'romrow',
|
||||
'romcell'
|
||||
));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
@@ -5,7 +5,8 @@
|
||||
<table style="width: 960px; max-width: 960px;" cellspacing="0">
|
||||
<tr>
|
||||
<td>
|
||||
<input type="datetime-local" id="logs_startdate" style="width: 30%;" /> <input type="datetime-local" id="logs_enddate" style="width: 30%;" />
|
||||
<input type="datetime-local" id="logs_startdate" style="width: 30%;" /> <input type="datetime-local"
|
||||
id="logs_enddate" style="width: 30%;" />
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" id="logs_type_info"><label for="logs_type_info">Information</label>
|
||||
@@ -35,7 +36,7 @@
|
||||
|
||||
<!-- <a href="#" class="romlink" onclick="loadLogs();" style="float: right;"><img src="/images/refresh.svg" alt="Refresh" title="Refresh" class="banner_button_image" /></a> -->
|
||||
<table id="settings_events_table" style="width: 960px; max-width: 960px;" cellspacing="0">
|
||||
|
||||
|
||||
</table>
|
||||
|
||||
<div style="width: 960px; text-align: center;">
|
||||
@@ -43,189 +44,7 @@
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var lastStartIndex = 0;
|
||||
var currentPage = 1;
|
||||
var searchModel = {};
|
||||
|
||||
var correlationIdParam = getQueryString('correlationid', 'string');
|
||||
if (correlationIdParam) {
|
||||
if (correlationIdParam.length > 0) {
|
||||
document.getElementById('logs_correlationid').value = correlationIdParam;
|
||||
}
|
||||
}
|
||||
|
||||
function resetFilters() {
|
||||
document.getElementById('logs_startdate').value = '';
|
||||
document.getElementById('logs_enddate').value = '';
|
||||
document.getElementById('logs_type_info').checked = false;
|
||||
document.getElementById('logs_type_warning').checked = false;
|
||||
document.getElementById('logs_type_critical').checked = false;
|
||||
document.getElementById('logs_textsearch').value = '';
|
||||
document.getElementById('logs_correlationid').value = '';
|
||||
|
||||
loadLogs();
|
||||
}
|
||||
|
||||
function loadLogs(StartIndex, PageNumber) {
|
||||
var model = {}
|
||||
|
||||
if (StartIndex && PageNumber) {
|
||||
currentPage += 1;
|
||||
|
||||
// get saved search model
|
||||
model = searchModel;
|
||||
model.StartIndex = StartIndex;
|
||||
model.PageNumber = PageNumber;
|
||||
} else {
|
||||
currentPage = 1;
|
||||
|
||||
// create search model
|
||||
var statusList = [];
|
||||
if (document.getElementById('logs_type_info').checked == true) { statusList.push(0); }
|
||||
if (document.getElementById('logs_type_warning').checked == true) { statusList.push(2); }
|
||||
if (document.getElementById('logs_type_critical').checked == true) { statusList.push(3); }
|
||||
var startDate = null;
|
||||
var startDateObj = document.getElementById('logs_startdate');
|
||||
if (startDateObj.value != null) { startDate = new Date(startDateObj.value); }
|
||||
var endDate = null;
|
||||
var endDateObj = document.getElementById('logs_enddate');
|
||||
if (endDateObj.value != null) { endDate = new Date(endDateObj.value); }
|
||||
var searchText = null;
|
||||
var searchTextObj = document.getElementById('logs_textsearch');
|
||||
if (searchTextObj.value != null) { searchText = searchTextObj.value; }
|
||||
var correlationId = null;
|
||||
var correlationIdTextObj = document.getElementById('logs_correlationid');
|
||||
if (correlationIdTextObj.value != null) { correlationId = correlationIdTextObj.value; }
|
||||
|
||||
model = {
|
||||
"StartIndex": StartIndex,
|
||||
"PageNumber": PageNumber,
|
||||
"PageSize": 100,
|
||||
"Status": statusList,
|
||||
"StartDateTime": startDate,
|
||||
"EndDateTime": endDate,
|
||||
"SearchText": searchText,
|
||||
"CorrelationId": correlationId
|
||||
}
|
||||
searchModel = model;
|
||||
}
|
||||
|
||||
console.log(model);
|
||||
|
||||
ajaxCall(
|
||||
'/api/v1.1/Logs',
|
||||
'POST',
|
||||
function (result) {
|
||||
var newTable = document.getElementById('settings_events_table');
|
||||
if (currentPage == 1) {
|
||||
newTable.innerHTML = '';
|
||||
|
||||
newTable.appendChild(
|
||||
createTableRow(
|
||||
true,
|
||||
[
|
||||
//'Id',
|
||||
['Event Time', 'logs_table_cell_150px'],
|
||||
['Severity', 'logs_table_cell_150px'],
|
||||
'Process',
|
||||
'Message'
|
||||
],
|
||||
'',
|
||||
''
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
lastStartIndex = result[i].id;
|
||||
|
||||
console.log(result[i]);
|
||||
|
||||
var surroundingRow = document.createElement('tbody');
|
||||
surroundingRow.setAttribute('colspan', 4);
|
||||
surroundingRow.className = 'logs_table_row_' + result[i].eventType;
|
||||
|
||||
var newRow = [
|
||||
moment(result[i].eventTime).format("YYYY-MM-DD h:mm:ss a"),
|
||||
result[i].eventType,
|
||||
result[i].process,
|
||||
result[i].message.replaceAll("\n", "<br />")
|
||||
];
|
||||
|
||||
surroundingRow.appendChild(createTableRow(false, newRow, '', 'romcell logs_table_cell'));
|
||||
|
||||
// exception
|
||||
var exceptionString = '';
|
||||
if (result[i].exceptionValue) {
|
||||
exceptionString = "<strong>Exception</strong><pre class='logs_table_exception' style='width: 795px; word-wrap: break-word; overflow-wrap: break-word; overflow-y: scroll;'>" + syntaxHighlight(JSON.stringify(result[i].exceptionValue, null, 2)).replace(/\\n/g, "<br /> ") + "</pre>";
|
||||
var exRow = document.createElement('tr');
|
||||
var leadCell = document.createElement('td');
|
||||
exRow.appendChild(leadCell);
|
||||
var exCell = document.createElement('td');
|
||||
exCell.colSpan = '3';
|
||||
exCell.innerHTML = exceptionString;
|
||||
exRow.appendChild(exCell);
|
||||
surroundingRow.appendChild(exRow);
|
||||
}
|
||||
|
||||
// calling process
|
||||
var infoRow = document.createElement('tr');
|
||||
|
||||
var infoRowEmptyCell = document.createElement('td');
|
||||
infoRowEmptyCell.className = 'romcell';
|
||||
|
||||
var infoRowDataCell = document.createElement('td');
|
||||
infoRowDataCell.className = 'romcell';
|
||||
infoRowDataCell.setAttribute('colspan', 3);
|
||||
infoRowDataCell.innerHTML = '<strong>Calling process:</strong> ' + result[i].callingProcess;
|
||||
|
||||
infoRow.appendChild(infoRowEmptyCell);
|
||||
infoRow.appendChild(infoRowDataCell);
|
||||
surroundingRow.appendChild(infoRow);
|
||||
|
||||
// initiated by user
|
||||
if (result[i].callingUser) {
|
||||
if (result[i].callingUser.length > 0) {
|
||||
var infoRow3 = document.createElement('tr');
|
||||
|
||||
var infoRowEmptyCell3 = document.createElement('td');
|
||||
infoRowEmptyCell3.className = 'romcell';
|
||||
|
||||
var infoRowDataCell3 = document.createElement('td');
|
||||
infoRowDataCell3.className = 'romcell';
|
||||
infoRowDataCell3.setAttribute('colspan', 3);
|
||||
infoRowDataCell3.innerHTML = '<strong>User:</strong> ' + result[i].callingUser + "</a>";
|
||||
|
||||
infoRow3.appendChild(infoRowEmptyCell3);
|
||||
infoRow3.appendChild(infoRowDataCell3);
|
||||
surroundingRow.appendChild(infoRow3);
|
||||
}
|
||||
}
|
||||
|
||||
// correlation id
|
||||
var infoRow2 = document.createElement('tr');
|
||||
|
||||
var infoRowEmptyCell2 = document.createElement('td');
|
||||
infoRowEmptyCell2.className = 'romcell';
|
||||
|
||||
var infoRowDataCell2 = document.createElement('td');
|
||||
infoRowDataCell2.className = 'romcell';
|
||||
infoRowDataCell2.setAttribute('colspan', 3);
|
||||
infoRowDataCell2.innerHTML = '<strong>Correlation Id:</strong> <a class="romlink" href="/index.html?page=settings&sub=logs&correlationid=' + result[i].correlationId + '">' + result[i].correlationId + "</a>";
|
||||
|
||||
infoRow2.appendChild(infoRowEmptyCell2);
|
||||
infoRow2.appendChild(infoRowDataCell2);
|
||||
surroundingRow.appendChild(infoRow2);
|
||||
|
||||
newTable.appendChild(surroundingRow);
|
||||
}
|
||||
},
|
||||
function (error) {
|
||||
|
||||
},
|
||||
JSON.stringify(model)
|
||||
);
|
||||
}
|
||||
|
||||
// load the logs
|
||||
initLogs();
|
||||
loadLogs();
|
||||
</script>
|
181
gaseous-server/wwwroot/pages/settings/logs.js
Normal file
181
gaseous-server/wwwroot/pages/settings/logs.js
Normal file
@@ -0,0 +1,181 @@
|
||||
let lastStartIndex = 0;
|
||||
let currentPage = 1;
|
||||
let searchModel = {};
|
||||
|
||||
function initLogs() {
|
||||
let correlationIdParam = getQueryString('correlationid', 'string');
|
||||
if (correlationIdParam) {
|
||||
if (correlationIdParam.length > 0) {
|
||||
document.getElementById('logs_correlationid').value = correlationIdParam;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resetFilters() {
|
||||
document.getElementById('logs_startdate').value = '';
|
||||
document.getElementById('logs_enddate').value = '';
|
||||
document.getElementById('logs_type_info').checked = false;
|
||||
document.getElementById('logs_type_warning').checked = false;
|
||||
document.getElementById('logs_type_critical').checked = false;
|
||||
document.getElementById('logs_textsearch').value = '';
|
||||
document.getElementById('logs_correlationid').value = '';
|
||||
|
||||
loadLogs();
|
||||
}
|
||||
|
||||
function loadLogs(StartIndex, PageNumber) {
|
||||
let model = {}
|
||||
|
||||
if (StartIndex && PageNumber) {
|
||||
currentPage += 1;
|
||||
|
||||
// get saved search model
|
||||
model = searchModel;
|
||||
model.StartIndex = StartIndex;
|
||||
model.PageNumber = PageNumber;
|
||||
} else {
|
||||
currentPage = 1;
|
||||
|
||||
// create search model
|
||||
let statusList = [];
|
||||
if (document.getElementById('logs_type_info').checked == true) { statusList.push(0); }
|
||||
if (document.getElementById('logs_type_warning').checked == true) { statusList.push(2); }
|
||||
if (document.getElementById('logs_type_critical').checked == true) { statusList.push(3); }
|
||||
let startDate = null;
|
||||
let startDateObj = document.getElementById('logs_startdate');
|
||||
if (startDateObj.value != null) { startDate = new Date(startDateObj.value); }
|
||||
let endDate = null;
|
||||
let endDateObj = document.getElementById('logs_enddate');
|
||||
if (endDateObj.value != null) { endDate = new Date(endDateObj.value); }
|
||||
let searchText = null;
|
||||
let searchTextObj = document.getElementById('logs_textsearch');
|
||||
if (searchTextObj.value != null) { searchText = searchTextObj.value; }
|
||||
let correlationId = null;
|
||||
let correlationIdTextObj = document.getElementById('logs_correlationid');
|
||||
if (correlationIdTextObj.value != null) { correlationId = correlationIdTextObj.value; }
|
||||
|
||||
model = {
|
||||
"StartIndex": StartIndex,
|
||||
"PageNumber": PageNumber,
|
||||
"PageSize": 100,
|
||||
"Status": statusList,
|
||||
"StartDateTime": startDate,
|
||||
"EndDateTime": endDate,
|
||||
"SearchText": searchText,
|
||||
"CorrelationId": correlationId
|
||||
}
|
||||
searchModel = model;
|
||||
}
|
||||
|
||||
ajaxCall(
|
||||
'/api/v1.1/Logs',
|
||||
'POST',
|
||||
function (result) {
|
||||
let newTable = document.getElementById('settings_events_table');
|
||||
if (currentPage == 1) {
|
||||
newTable.innerHTML = '';
|
||||
|
||||
newTable.appendChild(
|
||||
createTableRow(
|
||||
true,
|
||||
[
|
||||
//'Id',
|
||||
['Event Time', 'logs_table_cell_150px'],
|
||||
['Severity', 'logs_table_cell_150px'],
|
||||
'Process',
|
||||
'Message'
|
||||
],
|
||||
'',
|
||||
''
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
lastStartIndex = result[i].id;
|
||||
|
||||
let surroundingRow = document.createElement('tbody');
|
||||
surroundingRow.setAttribute('colspan', 4);
|
||||
surroundingRow.className = 'logs_table_row_' + result[i].eventType;
|
||||
|
||||
let newRow = [
|
||||
moment(result[i].eventTime).format("YYYY-MM-DD h:mm:ss a"),
|
||||
result[i].eventType,
|
||||
result[i].process,
|
||||
result[i].message.replaceAll("\n", "<br />")
|
||||
];
|
||||
|
||||
surroundingRow.appendChild(createTableRow(false, newRow, '', 'romcell logs_table_cell'));
|
||||
|
||||
// exception
|
||||
let exceptionString = '';
|
||||
if (result[i].exceptionValue) {
|
||||
exceptionString = "<strong>Exception</strong><pre class='logs_table_exception' style='width: 795px; word-wrap: break-word; overflow-wrap: break-word; overflow-y: scroll;'>" + syntaxHighlight(JSON.stringify(result[i].exceptionValue, null, 2)).replace(/\\n/g, "<br /> ") + "</pre>";
|
||||
let exRow = document.createElement('tr');
|
||||
let leadCell = document.createElement('td');
|
||||
exRow.appendChild(leadCell);
|
||||
let exCell = document.createElement('td');
|
||||
exCell.colSpan = '3';
|
||||
exCell.innerHTML = exceptionString;
|
||||
exRow.appendChild(exCell);
|
||||
surroundingRow.appendChild(exRow);
|
||||
}
|
||||
|
||||
// calling process
|
||||
let infoRow = document.createElement('tr');
|
||||
|
||||
let infoRowEmptyCell = document.createElement('td');
|
||||
infoRowEmptyCell.className = 'romcell';
|
||||
|
||||
let infoRowDataCell = document.createElement('td');
|
||||
infoRowDataCell.className = 'romcell';
|
||||
infoRowDataCell.setAttribute('colspan', 3);
|
||||
infoRowDataCell.innerHTML = '<strong>Calling process:</strong> ' + result[i].callingProcess;
|
||||
|
||||
infoRow.appendChild(infoRowEmptyCell);
|
||||
infoRow.appendChild(infoRowDataCell);
|
||||
surroundingRow.appendChild(infoRow);
|
||||
|
||||
// initiated by user
|
||||
if (result[i].callingUser) {
|
||||
if (result[i].callingUser.length > 0) {
|
||||
let infoRow3 = document.createElement('tr');
|
||||
|
||||
let infoRowEmptyCell3 = document.createElement('td');
|
||||
infoRowEmptyCell3.className = 'romcell';
|
||||
|
||||
let infoRowDataCell3 = document.createElement('td');
|
||||
infoRowDataCell3.className = 'romcell';
|
||||
infoRowDataCell3.setAttribute('colspan', 3);
|
||||
infoRowDataCell3.innerHTML = '<strong>User:</strong> ' + result[i].callingUser + "</a>";
|
||||
|
||||
infoRow3.appendChild(infoRowEmptyCell3);
|
||||
infoRow3.appendChild(infoRowDataCell3);
|
||||
surroundingRow.appendChild(infoRow3);
|
||||
}
|
||||
}
|
||||
|
||||
// correlation id
|
||||
let infoRow2 = document.createElement('tr');
|
||||
|
||||
let infoRowEmptyCell2 = document.createElement('td');
|
||||
infoRowEmptyCell2.className = 'romcell';
|
||||
|
||||
let infoRowDataCell2 = document.createElement('td');
|
||||
infoRowDataCell2.className = 'romcell';
|
||||
infoRowDataCell2.setAttribute('colspan', 3);
|
||||
infoRowDataCell2.innerHTML = '<strong>Correlation Id:</strong> <a class="romlink" href="/index.html?page=settings&sub=logs&correlationid=' + result[i].correlationId + '">' + result[i].correlationId + "</a>";
|
||||
|
||||
infoRow2.appendChild(infoRowEmptyCell2);
|
||||
infoRow2.appendChild(infoRowDataCell2);
|
||||
surroundingRow.appendChild(infoRow2);
|
||||
|
||||
newTable.appendChild(surroundingRow);
|
||||
}
|
||||
},
|
||||
function (error) {
|
||||
|
||||
},
|
||||
JSON.stringify(model)
|
||||
);
|
||||
}
|
@@ -1,98 +1,37 @@
|
||||
<div id="gametitle">
|
||||
<h1 id="gametitle_label">Platform Mapping</h1>
|
||||
<h1 id="gametitle_label">Platforms</h1>
|
||||
</div>
|
||||
|
||||
<p>When determining the platform of a ROM or image (which is later used when determining the game title), only the "Unique File Extensions" are used. All other extensions are ignored as they will limit the ability of Gaseous to determine the game title (see <a href="https://github.com/gaseous-project/gaseous-server#game-image-title-matching" class="romlink">https://github.com/gaseous-project/gaseous-server#game-image-title-matching</a> for more information on how matching works).</p>
|
||||
<div class="section">
|
||||
<div class="section-body">
|
||||
<p>When determining the platform of a ROM or image (which is later used when determining the game title), only
|
||||
the "Unique File Extensions" are used. All other extensions are ignored as they will limit the ability of
|
||||
Gaseous to determine the game title (see <a
|
||||
href="https://github.com/gaseous-project/gaseous-server/wiki/ROM-Metadata-Matching" class="romlink"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer">https://github.com/gaseous-project/gaseous-server/wiki/ROM-Metadata-Matching</a>
|
||||
for
|
||||
more
|
||||
information on how matching works).</p>
|
||||
|
||||
<p>This list is pre-populated with some of the more common platforms. New platforms will appear in this list as titles are added.</p>
|
||||
<p>This list is pre-populated with some of the more common platforms. New platforms will appear in this list as
|
||||
titles are added.</p>
|
||||
|
||||
<p id="settings_mapping_import" style="display: none;"><button value="Export to JSON" onclick="DownloadJSON();">Export to JSON</button><button id="importjson" value="Import JSON">Import JSON</button><button value="Reset to Default" onclick="loadPlatformMapping(true);">Reset to Default</button></p>
|
||||
<p id="settings_mapping_import" style="display: none;"><button value="Export to JSON"
|
||||
onclick="DownloadJSON();">Export to JSON</button><button id="importjson" value="Import JSON">Import
|
||||
JSON</button><button value="Reset to Default" onclick="loadPlatformMapping(true);">Reset to
|
||||
Default</button></p>
|
||||
|
||||
<input id='uploadjson' type='file' name='files' hidden/>
|
||||
<input id='uploadjson' type='file' name='files' hidden />
|
||||
|
||||
<table id="settings_mapping_table" style="width: 100%;" cellspacing="0">
|
||||
|
||||
</table>
|
||||
<table id="settings_mapping_table" style="width: 100%;" cellspacing="0">
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
if (userProfile.roles.includes("Admin")) {
|
||||
document.getElementById('settings_mapping_import').style.display = '';
|
||||
}
|
||||
|
||||
function loadPlatformMapping(Overwrite) {
|
||||
var queryString = '';
|
||||
if (Overwrite == true) {
|
||||
queryString = '?ResetToDefault=true';
|
||||
}
|
||||
|
||||
ajaxCall(
|
||||
'/api/v1.1/PlatformMaps' + queryString,
|
||||
'GET',
|
||||
function (result) {
|
||||
var newTable = document.getElementById('settings_mapping_table');
|
||||
newTable.innerHTML = '';
|
||||
newTable.appendChild(
|
||||
createTableRow(
|
||||
true,
|
||||
[
|
||||
'Platform',
|
||||
'Supported File Extensions',
|
||||
'Unique File Extensions',
|
||||
'Has Web Emulator'
|
||||
],
|
||||
'',
|
||||
''
|
||||
)
|
||||
);
|
||||
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
var hasWebEmulator = '';
|
||||
if (result[i].webEmulator.type.length > 0) {
|
||||
hasWebEmulator = 'Yes';
|
||||
}
|
||||
|
||||
var platformLink = '';
|
||||
if (userProfile.roles.includes("Admin")) {
|
||||
platformLink = '<a href="#/" onclick="ShowPlatformMappingDialog(' + result[i].igdbId + ');" class="romlink">' + result[i].igdbName + '</a>';
|
||||
} else {
|
||||
platformLink = result[i].igdbName;
|
||||
}
|
||||
|
||||
var newRow = [
|
||||
platformLink,
|
||||
result[i].extensions.supportedFileExtensions.join(', '),
|
||||
result[i].extensions.uniqueFileExtensions.join(', '),
|
||||
hasWebEmulator
|
||||
];
|
||||
|
||||
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell logs_table_cell'));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function DownloadJSON() {
|
||||
window.location = '/api/v1.1/PlatformMaps/PlatformMap.json';
|
||||
}
|
||||
|
||||
document.getElementById('importjson').addEventListener('click', openDialog);
|
||||
|
||||
function openDialog() {
|
||||
document.getElementById('uploadjson').click();
|
||||
}
|
||||
|
||||
$('#uploadjson').change(function () {
|
||||
$(this).simpleUpload("/api/v1.1/PlatformMaps", {
|
||||
start: function (file) {
|
||||
//upload started
|
||||
console.log("JSON upload started");
|
||||
},
|
||||
success: function(data){
|
||||
//upload successful
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Load the platform mapping
|
||||
SetupButtons();
|
||||
loadPlatformMapping();
|
||||
</script>
|
448
gaseous-server/wwwroot/pages/settings/mapping.js
Normal file
448
gaseous-server/wwwroot/pages/settings/mapping.js
Normal file
@@ -0,0 +1,448 @@
|
||||
function loadPlatformMapping(Overwrite) {
|
||||
let queryString = '';
|
||||
if (Overwrite == true) {
|
||||
console.log('Overwriting PlatformMap.json');
|
||||
queryString = '?ResetToDefault=true';
|
||||
}
|
||||
|
||||
ajaxCall(
|
||||
'/api/v1.1/PlatformMaps' + queryString,
|
||||
'GET',
|
||||
function (result) {
|
||||
let newTable = document.getElementById('settings_mapping_table');
|
||||
newTable.innerHTML = '';
|
||||
newTable.appendChild(
|
||||
createTableRow(
|
||||
true,
|
||||
[
|
||||
'Platform',
|
||||
'Supported File Extensions',
|
||||
'Unique File Extensions',
|
||||
'Has Web Emulator',
|
||||
''
|
||||
],
|
||||
'',
|
||||
''
|
||||
)
|
||||
);
|
||||
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
let hasWebEmulator = '';
|
||||
if (result[i].webEmulator.type.length > 0) {
|
||||
hasWebEmulator = 'Yes';
|
||||
}
|
||||
|
||||
let platformEditButton = null;
|
||||
if (userProfile.roles.includes("Admin")) {
|
||||
platformEditButton = document.createElement('div');
|
||||
platformEditButton.classList.add('romlink');
|
||||
platformEditButton.onclick = function () {
|
||||
let mappingModal = new Mapping(result[i].igdbId, loadPlatformMapping);
|
||||
mappingModal.open();
|
||||
};
|
||||
let editButtonImage = document.createElement('img');
|
||||
editButtonImage.src = '/images/edit.svg';
|
||||
editButtonImage.alt = 'Edit';
|
||||
editButtonImage.title = 'Edit';
|
||||
editButtonImage.classList.add('banner_button_image');
|
||||
platformEditButton.appendChild(editButtonImage);
|
||||
}
|
||||
|
||||
let newRow = [
|
||||
result[i].igdbName,
|
||||
result[i].extensions.supportedFileExtensions.join(', '),
|
||||
result[i].extensions.uniqueFileExtensions.join(', '),
|
||||
hasWebEmulator,
|
||||
platformEditButton
|
||||
];
|
||||
|
||||
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell logs_table_cell'));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function DownloadJSON() {
|
||||
window.location = '/api/v1.1/PlatformMaps/PlatformMap.json';
|
||||
}
|
||||
|
||||
function SetupButtons() {
|
||||
if (userProfile.roles.includes("Admin")) {
|
||||
document.getElementById('settings_mapping_import').style.display = '';
|
||||
|
||||
document.getElementById('uploadjson').addEventListener('change', function () {
|
||||
$(this).simpleUpload("/api/v1.1/PlatformMaps", {
|
||||
start: function (file) {
|
||||
//upload started
|
||||
console.log("JSON upload started");
|
||||
},
|
||||
success: function (data) {
|
||||
//upload successful
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById('importjson').addEventListener('click', openDialog);
|
||||
}
|
||||
}
|
||||
|
||||
function openDialog() {
|
||||
document.getElementById('uploadjson').click();
|
||||
}
|
||||
|
||||
class Mapping {
|
||||
constructor(PlatformId, OKCallback, CancelCallback) {
|
||||
this.PlatformId = PlatformId;
|
||||
this.OKCallback = OKCallback;
|
||||
this.CancelCallback = CancelCallback;
|
||||
}
|
||||
|
||||
async open() {
|
||||
// Create the modal
|
||||
this.dialog = await new Modal("mappings");
|
||||
await this.dialog.BuildModal();
|
||||
|
||||
// Get the platform data
|
||||
await fetch('/api/v1.1/PlatformMaps/' + this.PlatformId, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then(async response => {
|
||||
if (response.ok) {
|
||||
let result = await response.json();
|
||||
this.PlatformData = result;
|
||||
} else {
|
||||
let warningDialog = new MessageBox("Error", "Failed to load platform data", "OK");
|
||||
warningDialog.open();
|
||||
}
|
||||
});
|
||||
|
||||
// setup the dialog
|
||||
this.dialog.modalElement.querySelector('#modal-header-text').innerHTML = this.PlatformData.igdbName;
|
||||
|
||||
// setup general page
|
||||
this.alternateNames = this.dialog.modalElement.querySelector('#mapping_edit_alternativenames');
|
||||
$(this.alternateNames).select2({
|
||||
tags: true,
|
||||
tokenSeparators: [',']
|
||||
});
|
||||
this.#AddTokensFromList(this.alternateNames, this.PlatformData.alternateNames);
|
||||
|
||||
this.supportedFileExtensions = this.dialog.modalElement.querySelector('#mapping_edit_supportedfileextensions');
|
||||
$(this.supportedFileExtensions).select2({
|
||||
tags: true,
|
||||
tokenSeparators: [','],
|
||||
createTag: function (params) {
|
||||
if (params.term.indexOf('.') === -1) {
|
||||
// Return null to disable tag creation
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
id: params.term.toUpperCase(),
|
||||
text: params.term.toUpperCase()
|
||||
}
|
||||
}
|
||||
});
|
||||
this.#AddTokensFromList(this.supportedFileExtensions, this.PlatformData.extensions.supportedFileExtensions);
|
||||
|
||||
this.dialog.modalElement.querySelector('#mapping_edit_igdbslug').value = this.PlatformData.igdbSlug;
|
||||
this.dialog.modalElement.querySelector('#mapping_edit_retropie').value = this.PlatformData.retroPieDirectoryName;
|
||||
|
||||
// setup the emulator page
|
||||
this.webEmulatorConfiguration = new WebEmulatorConfiguration(this.PlatformData);
|
||||
await this.webEmulatorConfiguration.open();
|
||||
this.dialog.modalElement.querySelector('#mapping_edit_webemulator').appendChild(this.webEmulatorConfiguration.panel);
|
||||
|
||||
// setup the buttons
|
||||
let okButton = new ModalButton("OK", 1, this, async function (callingObject) {
|
||||
callingObject.PlatformData.alternateNames = $(callingObject.alternateNames).val();
|
||||
callingObject.PlatformData.extensions.supportedFileExtensions = $(callingObject.supportedFileExtensions).val();
|
||||
callingObject.PlatformData.retroPieDirectoryName = callingObject.dialog.modalElement.querySelector('#mapping_edit_retropie').value;
|
||||
callingObject.PlatformData.webEmulator.type = callingObject.webEmulatorConfiguration.PlatformMap.webEmulator.type;
|
||||
callingObject.PlatformData.webEmulator.core = callingObject.webEmulatorConfiguration.PlatformMap.webEmulator.core;
|
||||
callingObject.PlatformData.enabledBIOSHashes = callingObject.webEmulatorConfiguration.PlatformMap.enabledBIOSHashes;
|
||||
|
||||
await fetch('/api/v1.1/PlatformMaps/' + callingObject.PlatformId, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(callingObject.PlatformData)
|
||||
}).then(async response => {
|
||||
if (response.ok) {
|
||||
let result = await response.json();
|
||||
|
||||
if (callingObject.OKCallback) {
|
||||
callingObject.OKCallback();
|
||||
}
|
||||
|
||||
callingObject.dialog.close();
|
||||
} else {
|
||||
let warningDialog = new Dialog("Error", "Failed to save platform data", "OK");
|
||||
warningDialog.open();
|
||||
}
|
||||
});
|
||||
});
|
||||
this.dialog.addButton(okButton);
|
||||
|
||||
// create the cancel button
|
||||
let cancelButton = new ModalButton("Cancel", 0, this, function (callingObject) {
|
||||
if (callingObject.CancelCallback) {
|
||||
callingObject.CancelCallback();
|
||||
}
|
||||
|
||||
callingObject.dialog.close();
|
||||
});
|
||||
this.dialog.addButton(cancelButton);
|
||||
|
||||
this.dialog.open();
|
||||
}
|
||||
|
||||
#AddTokensFromList(selectObj, tagList) {
|
||||
for (let i = 0; i < tagList.length; i++) {
|
||||
let data = {
|
||||
id: tagList[i],
|
||||
text: tagList[i]
|
||||
}
|
||||
|
||||
let newOption = new Option(data.text, data.id, true, true);
|
||||
$(selectObj).append(newOption).trigger('change');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class WebEmulatorConfiguration {
|
||||
constructor(PlatformMap) {
|
||||
this.PlatformMap = PlatformMap;
|
||||
|
||||
if (this.PlatformMap.bios.length > 0) {
|
||||
this.PlatformMap.bios.sort((a, b) => (a.description > b.description) ? 1 : ((b.description > a.description) ? -1 : 0))
|
||||
}
|
||||
}
|
||||
|
||||
async open() {
|
||||
// create the panel
|
||||
this.panel = document.createElement('div');
|
||||
const templateResponse = await fetch('/pages/modals/webemulator.html');
|
||||
const templateContent = await templateResponse.text();
|
||||
this.panel.innerHTML = templateContent;
|
||||
|
||||
// load the emulator list
|
||||
this.#LoadEmulatorList();
|
||||
|
||||
// select the emulator and core
|
||||
if (this.PlatformMap.webEmulator.type.length === 0) {
|
||||
this.PlatformMap.webEmulator.type = 'none';
|
||||
}
|
||||
let emulatorSelect = this.panel.querySelector('#webemulator_select_' + this.PlatformMap.webEmulator.type);
|
||||
if (emulatorSelect != null) {
|
||||
emulatorSelect.checked = true;
|
||||
this.#LoadCoreList(this.PlatformMap.webEmulator.type);
|
||||
let coreSelect = this.panel.querySelector('#webemulator_core_select_' + this.PlatformMap.webEmulator.core);
|
||||
if (coreSelect != null) {
|
||||
coreSelect.checked = true;
|
||||
}
|
||||
}
|
||||
this.#EmulatorInfoPanels();
|
||||
|
||||
// load the bios list
|
||||
this.#LoadBiosList();
|
||||
}
|
||||
|
||||
#LoadEmulatorList() {
|
||||
let emulatorSelect = this.panel.querySelector('#webemulator_select');
|
||||
|
||||
let emulatorSelectTable = document.createElement('table');
|
||||
|
||||
// create radio button list of available web emulators
|
||||
let emulatorSelectTableRow = document.createElement('tr');
|
||||
let emulatorSelectTableCell = document.createElement('td');
|
||||
|
||||
let newOption = document.createElement('input');
|
||||
newOption.id = 'webemulator_select_none';
|
||||
newOption.name = 'webemulator_select';
|
||||
newOption.type = 'radio';
|
||||
newOption.value = '';
|
||||
newOption.addEventListener('change', () => {
|
||||
this.#LoadCoreList('');
|
||||
this.PlatformMap.webEmulator.type = '';
|
||||
|
||||
this.#EmulatorInfoPanels();
|
||||
});
|
||||
emulatorSelectTableCell.appendChild(newOption);
|
||||
|
||||
let newLabel = document.createElement('label');
|
||||
newLabel.htmlFor = 'webemulator_select_none';
|
||||
newLabel.innerHTML = ' None';
|
||||
emulatorSelectTableCell.appendChild(newLabel);
|
||||
|
||||
emulatorSelectTableRow.appendChild(emulatorSelectTableCell);
|
||||
emulatorSelectTable.appendChild(emulatorSelectTableRow);
|
||||
|
||||
if (this.PlatformMap.webEmulator.availableWebEmulators) {
|
||||
if (this.PlatformMap.webEmulator.availableWebEmulators.length > 0) {
|
||||
for (let i = 0; i < this.PlatformMap.webEmulator.availableWebEmulators.length; i++) {
|
||||
let emulatorSelectTableRow = document.createElement('tr');
|
||||
let emulatorSelectTableCell = document.createElement('td');
|
||||
|
||||
let newOption = document.createElement('input');
|
||||
newOption.id = 'webemulator_select_' + this.PlatformMap.webEmulator.availableWebEmulators[i].emulatorType;
|
||||
newOption.name = 'webemulator_select';
|
||||
newOption.type = 'radio';
|
||||
newOption.value = this.PlatformMap.webEmulator.availableWebEmulators[i].emulatorType;
|
||||
newOption.addEventListener('change', () => {
|
||||
this.#LoadCoreList(this.PlatformMap.webEmulator.availableWebEmulators[i].emulatorType);
|
||||
this.PlatformMap.webEmulator.type = this.PlatformMap.webEmulator.availableWebEmulators[i].emulatorType;
|
||||
|
||||
this.#EmulatorInfoPanels();
|
||||
});
|
||||
emulatorSelectTableCell.appendChild(newOption);
|
||||
|
||||
let newLabel = document.createElement('label');
|
||||
newLabel.htmlFor = 'webemulator_select_' + this.PlatformMap.webEmulator.availableWebEmulators[i].emulatorType;
|
||||
newLabel.innerHTML = " " + this.PlatformMap.webEmulator.availableWebEmulators[i].emulatorType;
|
||||
emulatorSelectTableCell.appendChild(newLabel);
|
||||
|
||||
emulatorSelectTableRow.appendChild(emulatorSelectTableCell);
|
||||
emulatorSelectTable.appendChild(emulatorSelectTableRow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emulatorSelect.appendChild(emulatorSelectTable);
|
||||
}
|
||||
|
||||
#EmulatorInfoPanels() {
|
||||
// show appropriate emulator info panel
|
||||
switch (this.PlatformMap.webEmulator.type) {
|
||||
case 'EmulatorJS':
|
||||
this.panel.querySelector('#webemulator_info_emulatorjs').style.display = '';
|
||||
break;
|
||||
|
||||
default:
|
||||
this.panel.querySelector('#webemulator_info_emulatorjs').style.display = 'none';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#LoadCoreList(EmulatorType) {
|
||||
let coreSelectSection = this.panel.querySelector('#webemulator_core_select-section');
|
||||
coreSelectSection.style.display = 'none';
|
||||
|
||||
// show core help (if available)
|
||||
switch (EmulatorType) {
|
||||
case 'EmulatorJS':
|
||||
this.panel.querySelector('#webemulator_core_info_emulatorjs').style.display = '';
|
||||
break;
|
||||
}
|
||||
|
||||
let coreSelect = this.panel.querySelector('#webemulator_core_select');
|
||||
coreSelect.innerHTML = '';
|
||||
|
||||
let coreSelectTable = document.createElement('table');
|
||||
|
||||
if (this.PlatformMap.webEmulator.availableWebEmulators) {
|
||||
if (this.PlatformMap.webEmulator.availableWebEmulators.length > 0) {
|
||||
for (let i = 0; i < this.PlatformMap.webEmulator.availableWebEmulators.length; i++) {
|
||||
if (this.PlatformMap.webEmulator.availableWebEmulators[i].emulatorType == EmulatorType) {
|
||||
for (let j = 0; j < this.PlatformMap.webEmulator.availableWebEmulators[i].availableWebEmulatorCores.length; j++) {
|
||||
coreSelectSection.style.display = '';
|
||||
|
||||
let coreSelectTableRow = document.createElement('tr');
|
||||
let coreSelectTableCell = document.createElement('td');
|
||||
|
||||
let newOption = document.createElement('input');
|
||||
newOption.id = 'webemulator_core_select_' + this.PlatformMap.webEmulator.availableWebEmulators[i].availableWebEmulatorCores[j].core;
|
||||
newOption.name = 'webemulator_core_select';
|
||||
newOption.type = 'radio';
|
||||
newOption.value = this.PlatformMap.webEmulator.availableWebEmulators[i].availableWebEmulatorCores[j].core;
|
||||
newOption.text = this.PlatformMap.webEmulator.availableWebEmulators[i].availableWebEmulatorCores[j].core;
|
||||
if (this.PlatformMap.webEmulator.availableWebEmulators[i].availableWebEmulatorCores[j].default == true) {
|
||||
newOption.checked = true;
|
||||
}
|
||||
newOption.addEventListener('change', () => {
|
||||
this.PlatformMap.webEmulator.core = this.PlatformMap.webEmulator.availableWebEmulators[i].availableWebEmulatorCores[j].core;
|
||||
});
|
||||
coreSelectTableCell.appendChild(newOption);
|
||||
|
||||
let newLabel = document.createElement('label');
|
||||
newLabel.htmlFor = 'webemulator_core_select_' + this.PlatformMap.webEmulator.availableWebEmulators[i].availableWebEmulatorCores[j].core;
|
||||
let labelText = "";
|
||||
if (this.PlatformMap.webEmulator.availableWebEmulators[i].availableWebEmulatorCores[j].alternateCoreName.length > 0) {
|
||||
labelText = " " + this.PlatformMap.webEmulator.availableWebEmulators[i].availableWebEmulatorCores[j].core + " (maps to core: " + this.PlatformMap.webEmulator.availableWebEmulators[i].availableWebEmulatorCores[j].alternateCoreName + ")";
|
||||
} else {
|
||||
labelText = " " + this.PlatformMap.webEmulator.availableWebEmulators[i].availableWebEmulatorCores[j].core;
|
||||
}
|
||||
if (this.PlatformMap.webEmulator.availableWebEmulators[i].availableWebEmulatorCores[j].default == true) {
|
||||
labelText += " (Default)";
|
||||
}
|
||||
newLabel.innerHTML = labelText;
|
||||
coreSelectTableCell.appendChild(newLabel);
|
||||
|
||||
coreSelectTableRow.appendChild(coreSelectTableCell);
|
||||
coreSelectTable.appendChild(coreSelectTableRow);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
coreSelect.appendChild(coreSelectTable);
|
||||
}
|
||||
|
||||
#LoadBiosList() {
|
||||
if (this.PlatformMap.bios.length > 0) {
|
||||
let biosSelect = this.panel.querySelector('#webemulator_bios_select');
|
||||
biosSelect.innerHTML = '';
|
||||
|
||||
let biosSelectTable = document.createElement('table');
|
||||
biosSelectTable.style.width = '100%';
|
||||
for (let i = 0; i < this.PlatformMap.bios.length; i++) {
|
||||
let biosSelectTableRow = document.createElement('tr');
|
||||
biosSelectTableRow.classList.add('romrow');
|
||||
let biosSelectTableCell = document.createElement('td');
|
||||
biosSelectTableCell.classList.add('romcell');
|
||||
|
||||
let newOption = document.createElement('input');
|
||||
newOption.id = 'webemulator_bios_select_' + this.PlatformMap.bios[i].hash;
|
||||
newOption.name = 'webemulator_bios_select';
|
||||
newOption.type = 'checkbox';
|
||||
newOption.value = this.PlatformMap.bios[i].hash;
|
||||
if (this.PlatformMap.enabledBIOSHashes.includes(this.PlatformMap.bios[i].hash)) {
|
||||
newOption.checked = true;
|
||||
}
|
||||
newOption.addEventListener('change', () => {
|
||||
if (newOption.checked) {
|
||||
this.PlatformMap.enabledBIOSHashes.push(this.PlatformMap.bios[i].hash);
|
||||
} else {
|
||||
let index = this.PlatformMap.enabledBIOSHashes.indexOf(this.PlatformMap.bios[i].hash);
|
||||
if (index > -1) {
|
||||
this.PlatformMap.enabledBIOSHashes.splice(index, 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
biosSelectTableCell.appendChild(newOption);
|
||||
|
||||
let newLabel = document.createElement('label');
|
||||
newLabel.htmlFor = 'webemulator_bios_select_' + this.PlatformMap.bios[i].hash;
|
||||
let labelText = "";
|
||||
if (this.PlatformMap.bios[i].description.length > 0) {
|
||||
labelText = this.PlatformMap.bios[i].description + " (" + this.PlatformMap.bios[i].filename + ")";
|
||||
} else {
|
||||
labelText = this.PlatformMap.bios[i].filename;
|
||||
}
|
||||
newLabel.innerHTML = " " + labelText;
|
||||
biosSelectTableCell.appendChild(newLabel);
|
||||
|
||||
biosSelectTableRow.appendChild(biosSelectTableCell);
|
||||
biosSelectTable.appendChild(biosSelectTableRow);
|
||||
}
|
||||
biosSelect.appendChild(biosSelectTable);
|
||||
} else {
|
||||
this.panel.querySelector('#webemulator_bios_select-section').style.display = 'none';
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,290 +1,16 @@
|
||||
<div id="gametitle">
|
||||
<h1 id="gametitle_label">Services</h1>
|
||||
</div>
|
||||
<table id="settings_tasktimers" class="romtable" style="width: 100%;" cellspacing="0">
|
||||
|
||||
</table>
|
||||
<div style="text-align: right;"><button id="settings_tasktimers_default" onclick="defaultTaskTimers();">Reset to
|
||||
Default</button><button id="settings_tasktimers_new" onclick="saveTaskTimers();">Save</button></div>
|
||||
<div class="section">
|
||||
<div id="settings_tasktimers" style="width: 100%;">
|
||||
|
||||
</div>
|
||||
<div style="text-align: right;"><button id="settings_tasktimers_default" onclick="defaultTaskTimers();">Reset to
|
||||
Default</button><button id="settings_tasktimers_new" onclick="saveTaskTimers();">Save</button></div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function getBackgroundTaskTimers() {
|
||||
ajaxCall(
|
||||
'/api/v1/System/Settings/BackgroundTasks/Configuration',
|
||||
'GET',
|
||||
function (result) {
|
||||
var targetTable = document.getElementById('settings_tasktimers');
|
||||
targetTable.innerHTML = '';
|
||||
|
||||
for (const [key, value] of Object.entries(result)) {
|
||||
var newTableRowBody = document.createElement('tbody');
|
||||
newTableRowBody.className = 'romrow';
|
||||
|
||||
var enabledString = "";
|
||||
if (value.enabled == true) {
|
||||
enabledString = 'checked="checked"';
|
||||
}
|
||||
|
||||
var newTableIntervalRow = createTableRow(
|
||||
false,
|
||||
[
|
||||
GetTaskFriendlyName(value.task),
|
||||
'Enabled',
|
||||
'<input id="settings_enabled_' + value.task + '" name="settings_tasktimers_enabled" type="checkbox" ' + enabledString + '/>',
|
||||
],
|
||||
'',
|
||||
'romcell'
|
||||
);
|
||||
newTableRowBody.appendChild(newTableIntervalRow);
|
||||
|
||||
var newTableRow = createTableRow(
|
||||
false,
|
||||
[
|
||||
'',
|
||||
'Minimum Interval (Minutes):',
|
||||
'<input id="settings_tasktimers_' + value.task + '" name="settings_tasktimers_values" data-name="' + value.task + '" data-default="' + value.defaultInterval + '" type="number" placeholder="' + value.defaultInterval + '" min="' + value.minimumAllowedInterval + '" value="' + value.interval + '" />'
|
||||
],
|
||||
'',
|
||||
'romcell'
|
||||
);
|
||||
newTableRowBody.appendChild(newTableRow);
|
||||
|
||||
// allowed time periods row
|
||||
var newTableRowTime = document.createElement('tr');
|
||||
var rowTimeSpace = document.createElement('td');
|
||||
newTableRowTime.appendChild(rowTimeSpace);
|
||||
|
||||
var rowTimeContentTitle = document.createElement('td');
|
||||
rowTimeContentTitle.className = 'romcell';
|
||||
rowTimeContentTitle.innerHTML = "Allowed Days:";
|
||||
newTableRowTime.appendChild(rowTimeContentTitle);
|
||||
|
||||
var rowTimeContent = document.createElement('td');
|
||||
// rowTimeContent.setAttribute('colspan', 2);
|
||||
rowTimeContent.className = 'romcell';
|
||||
var daySelector = document.createElement('select');
|
||||
daySelector.id = 'settings_alloweddays_' + value.task;
|
||||
daySelector.name = 'settings_alloweddays';
|
||||
daySelector.multiple = 'multiple';
|
||||
daySelector.setAttribute('data-default', value.defaultAllowedDays.join(","));
|
||||
daySelector.style.width = '95%';
|
||||
var days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
|
||||
for (var d = 0; d < days.length; d++) {
|
||||
var dayOpt = document.createElement('option');
|
||||
dayOpt.value = days[d];
|
||||
dayOpt.innerHTML = days[d];
|
||||
if (value.allowedDays.includes(days[d])) {
|
||||
dayOpt.selected = 'selected';
|
||||
}
|
||||
daySelector.appendChild(dayOpt);
|
||||
}
|
||||
rowTimeContent.appendChild(daySelector);
|
||||
$(daySelector).select2({
|
||||
tags: false
|
||||
});
|
||||
newTableRowTime.appendChild(rowTimeContent);
|
||||
|
||||
newTableRowBody.appendChild(newTableRowTime);
|
||||
|
||||
// add start and end times
|
||||
var newTableRowClock = document.createElement('tr');
|
||||
var rowClockSpace = document.createElement('td');
|
||||
newTableRowClock.appendChild(rowClockSpace);
|
||||
|
||||
var rowClockContentTitle = document.createElement('td');
|
||||
rowClockContentTitle.className = 'romcell';
|
||||
rowClockContentTitle.innerHTML = "Time Range:";
|
||||
newTableRowClock.appendChild(rowClockContentTitle);
|
||||
|
||||
var rowClockContent = document.createElement('td');
|
||||
rowClockContent.className = 'romcell';
|
||||
// rowClockContent.setAttribute('colspan', 2);
|
||||
|
||||
rowClockContent.appendChild(generateTimeDropDowns(value.task, 'Start', value.defaultAllowedStartHours, value.defaultAllowedStartMinutes, value.allowedStartHours, value.allowedStartMinutes));
|
||||
|
||||
rowClockContentSeparator = document.createElement('span');
|
||||
rowClockContentSeparator.innerHTML = ' - ';
|
||||
rowClockContent.appendChild(rowClockContentSeparator);
|
||||
|
||||
rowClockContent.appendChild(generateTimeDropDowns(value.task, 'End', value.defaultAllowedEndHours, value.defaultAllowedEndMinutes, value.allowedEndHours, value.allowedEndMinutes));
|
||||
|
||||
newTableRowClock.appendChild(rowClockContent);
|
||||
|
||||
newTableRowBody.appendChild(newTableRowClock);
|
||||
|
||||
// blocks tasks
|
||||
var newTableRowBlocks = document.createElement('tr');
|
||||
var rowBlocksSpace = document.createElement('td');
|
||||
newTableRowBlocks.appendChild(rowBlocksSpace);
|
||||
|
||||
var rowBlocksContentTitle = document.createElement('td');
|
||||
rowBlocksContentTitle.className = 'romcell';
|
||||
rowBlocksContentTitle.innerHTML = "Blocks:";
|
||||
newTableRowBlocks.appendChild(rowBlocksContentTitle);
|
||||
|
||||
var rowBlocksContent = document.createElement('td');
|
||||
rowBlocksContent.className = 'romcell';
|
||||
// rowBlocksContent.setAttribute('colspan', 2);
|
||||
var blocksString = "";
|
||||
for (var i = 0; i < value.blocks.length; i++) {
|
||||
if (blocksString.length > 0) { blocksString += ", "; }
|
||||
blocksString += GetTaskFriendlyName(value.blocks[i]);
|
||||
}
|
||||
if (blocksString.length == 0) { blocksString = 'None'; }
|
||||
rowBlocksContent.innerHTML = blocksString;
|
||||
newTableRowBlocks.appendChild(rowBlocksContent);
|
||||
|
||||
newTableRowBody.appendChild(newTableRowBlocks);
|
||||
|
||||
// blocked by tasks
|
||||
var newTableRowBlockedBy = document.createElement('tr');
|
||||
var rowBlockedBySpace = document.createElement('td');
|
||||
newTableRowBlockedBy.appendChild(rowBlockedBySpace);
|
||||
|
||||
var rowBlockedByContentTitle = document.createElement('td');
|
||||
rowBlockedByContentTitle.className = 'romcell';
|
||||
rowBlockedByContentTitle.innerHTML = "Blocked By:";
|
||||
newTableRowBlockedBy.appendChild(rowBlockedByContentTitle);
|
||||
|
||||
var rowBlockedByContent = document.createElement('td');
|
||||
rowBlockedByContent.className = 'romcell';
|
||||
// rowBlockedByContent.setAttribute('colspan', 2);
|
||||
var BlockedByString = "";
|
||||
for (var i = 0; i < value.blockedBy.length; i++) {
|
||||
if (BlockedByString.length > 0) { BlockedByString += ", "; }
|
||||
BlockedByString += GetTaskFriendlyName(value.blockedBy[i]);
|
||||
}
|
||||
if (BlockedByString.length == 0) { BlockedByString = 'None'; }
|
||||
rowBlockedByContent.innerHTML = BlockedByString;
|
||||
newTableRowBlockedBy.appendChild(rowBlockedByContent);
|
||||
|
||||
newTableRowBody.appendChild(newTableRowBlockedBy);
|
||||
|
||||
// complete row
|
||||
targetTable.appendChild(newTableRowBody);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function generateTimeDropDowns(taskName, rangeName, defaultHour, defaultMinute, valueHour, valueMinute) {
|
||||
var container = document.createElement('div');
|
||||
container.style.display = 'inline';
|
||||
|
||||
var elementName = 'settings_tasktimers_time';
|
||||
|
||||
var hourSelector = document.createElement('input');
|
||||
hourSelector.id = 'settings_tasktimers_' + taskName + '_' + rangeName + '_Hour';
|
||||
hourSelector.name = elementName;
|
||||
hourSelector.setAttribute('data-name', taskName);
|
||||
hourSelector.setAttribute('type', 'number');
|
||||
hourSelector.setAttribute('min', '0');
|
||||
hourSelector.setAttribute('max', '23');
|
||||
hourSelector.setAttribute('placeholder', defaultHour);
|
||||
hourSelector.value = valueHour;
|
||||
container.appendChild(hourSelector);
|
||||
|
||||
var separator = document.createElement('span');
|
||||
separator.innerHTML = " : ";
|
||||
container.appendChild(separator);
|
||||
|
||||
var minSelector = document.createElement('input');
|
||||
minSelector.id = 'settings_tasktimers_' + taskName + '_' + rangeName + '_Minute';
|
||||
minSelector.name = elementName;
|
||||
minSelector.setAttribute('type', 'number');
|
||||
minSelector.setAttribute('min', '0');
|
||||
minSelector.setAttribute('max', '59');
|
||||
minSelector.setAttribute('placeholder', defaultMinute);
|
||||
minSelector.value = valueMinute;
|
||||
container.appendChild(minSelector);
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
function saveTaskTimers() {
|
||||
var timerValues = document.getElementsByName('settings_tasktimers_values');
|
||||
|
||||
var model = [];
|
||||
for (var i = 0; i < timerValues.length; i++) {
|
||||
var taskName = timerValues[i].getAttribute('data-name');
|
||||
var taskEnabled = document.getElementById('settings_enabled_' + taskName).checked;
|
||||
var taskIntervalObj = document.getElementById('settings_tasktimers_' + taskName);
|
||||
var taskInterval = function () { if (taskIntervalObj.value) { return taskIntervalObj.value; } else { return taskIntervalObj.getAttribute('placeholder'); } };
|
||||
var taskDaysRaw = $('#settings_alloweddays_' + taskName).select2('data');
|
||||
var taskDays = [];
|
||||
if (taskDaysRaw.length > 0) {
|
||||
for (var d = 0; d < taskDaysRaw.length; d++) {
|
||||
taskDays.push(taskDaysRaw[d].id);
|
||||
}
|
||||
} else {
|
||||
taskDays.push("Monday");
|
||||
}
|
||||
var taskStartHourObj = document.getElementById('settings_tasktimers_' + taskName + '_Start_Hour');
|
||||
var taskStartMinuteObj = document.getElementById('settings_tasktimers_' + taskName + '_Start_Minute');
|
||||
var taskEndHourObj = document.getElementById('settings_tasktimers_' + taskName + '_End_Hour');
|
||||
var taskEndMinuteObj = document.getElementById('settings_tasktimers_' + taskName + '_End_Minute');
|
||||
|
||||
var taskStartHour = function () { if (taskStartHourObj.value) { return taskStartHourObj.value; } else { return taskStartHourObj.getAttribute('placeholder'); } };
|
||||
var taskStartMinute = function () { if (taskStartMinuteObj.value) { return taskStartMinuteObj.value; } else { return taskStartMinuteObj.getAttribute('placeholder'); } };
|
||||
var taskEndHour = function () { if (taskEndHourObj.value) { return taskEndHourObj.value; } else { return taskEndHourObj.getAttribute('placeholder'); } };
|
||||
var taskEndMinute = function () { if (taskEndMinuteObj.value) { return taskEndMinuteObj.value; } else { return taskEndMinuteObj.getAttribute('placeholder'); } };
|
||||
|
||||
model.push(
|
||||
{
|
||||
"task": taskName,
|
||||
"enabled": taskEnabled,
|
||||
"interval": taskInterval(),
|
||||
"allowedDays": taskDays,
|
||||
"allowedStartHours": taskStartHour(),
|
||||
"allowedStartMinutes": taskStartMinute(),
|
||||
"allowedEndHours": taskEndHour(),
|
||||
"allowedEndMinutes": taskEndMinute()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
ajaxCall(
|
||||
'/api/v1/System/Settings/BackgroundTasks/Configuration',
|
||||
'POST',
|
||||
function (result) {
|
||||
getBackgroundTaskTimers();
|
||||
},
|
||||
function (error) {
|
||||
getBackgroundTaskTimers();
|
||||
},
|
||||
JSON.stringify(model)
|
||||
);
|
||||
}
|
||||
|
||||
function defaultTaskTimers() {
|
||||
var timerValues = document.getElementsByName('settings_tasktimers_enabled');
|
||||
|
||||
for (var i = 0; i < timerValues.length; i++) {
|
||||
timerValues[i].checked = true;
|
||||
}
|
||||
|
||||
var timerValues = document.getElementsByName('settings_tasktimers_values');
|
||||
|
||||
for (var i = 0; i < timerValues.length; i++) {
|
||||
timerValues[i].value = timerValues[i].getAttribute('data-default');
|
||||
}
|
||||
|
||||
var timerValues = document.getElementsByName('settings_alloweddays');
|
||||
|
||||
for (var i = 0; i < timerValues.length; i++) {
|
||||
var defaultSelections = timerValues[i].getAttribute('data-default').split(',');
|
||||
$(timerValues[i]).val(defaultSelections);
|
||||
$(timerValues[i]).trigger('change');
|
||||
}
|
||||
|
||||
var timerValues = document.getElementsByName('settings_tasktimers_time');
|
||||
|
||||
for (var i = 0; i < timerValues.length; i++) {
|
||||
timerValues[i].value = timerValues[i].getAttribute('placeholder');
|
||||
}
|
||||
|
||||
saveTaskTimers();
|
||||
}
|
||||
|
||||
// populate the page
|
||||
getBackgroundTaskTimers();
|
||||
</script>
|
297
gaseous-server/wwwroot/pages/settings/services.js
Normal file
297
gaseous-server/wwwroot/pages/settings/services.js
Normal file
@@ -0,0 +1,297 @@
|
||||
function getBackgroundTaskTimers() {
|
||||
ajaxCall(
|
||||
'/api/v1/System/Settings/BackgroundTasks/Configuration',
|
||||
'GET',
|
||||
function (result) {
|
||||
let targetTable = document.getElementById('settings_tasktimers');
|
||||
targetTable.innerHTML = '';
|
||||
|
||||
for (const [key, value] of Object.entries(result)) {
|
||||
let enabledString = "";
|
||||
if (value.enabled == true) {
|
||||
enabledString = 'checked="checked"';
|
||||
}
|
||||
|
||||
// add heading
|
||||
let serviceHeader = document.createElement('div');
|
||||
serviceHeader.className = 'section-header';
|
||||
serviceHeader.innerHTML = GetTaskFriendlyName(value.task);
|
||||
targetTable.appendChild(serviceHeader);
|
||||
|
||||
// create table for each service
|
||||
let serviceTable = document.createElement('table');
|
||||
serviceTable.style.width = '100%';
|
||||
serviceTable.classList.add('section-body');
|
||||
|
||||
// add enabled
|
||||
let newEnabledRow = document.createElement('tr');
|
||||
|
||||
let newEnabledTitle = document.createElement('td');
|
||||
newEnabledTitle.className = 'romcell romcell-headercell';
|
||||
newEnabledTitle.innerHTML = "Enabled:";
|
||||
newEnabledRow.appendChild(newEnabledTitle);
|
||||
|
||||
let newEnabledContent = document.createElement('td');
|
||||
newEnabledContent.className = 'romcell';
|
||||
let newEnabledCheckbox = document.createElement('input');
|
||||
newEnabledCheckbox.id = 'settings_enabled_' + value.task;
|
||||
newEnabledCheckbox.name = 'settings_tasktimers_enabled';
|
||||
newEnabledCheckbox.type = 'checkbox';
|
||||
newEnabledCheckbox.checked = value.enabled;
|
||||
newEnabledContent.appendChild(newEnabledCheckbox);
|
||||
newEnabledRow.appendChild(newEnabledContent);
|
||||
|
||||
serviceTable.appendChild(newEnabledRow);
|
||||
|
||||
// add interval
|
||||
let newIntervalRow = document.createElement('tr');
|
||||
|
||||
let newIntervalTitle = document.createElement('td');
|
||||
newIntervalTitle.className = 'romcell romcell-headercell';
|
||||
newIntervalTitle.innerHTML = "Minimum Interval (Minutes):";
|
||||
newIntervalRow.appendChild(newIntervalTitle);
|
||||
|
||||
let newIntervalContent = document.createElement('td');
|
||||
newIntervalContent.className = 'romcell';
|
||||
let newIntervalInput = document.createElement('input');
|
||||
newIntervalInput.id = 'settings_tasktimers_' + value.task;
|
||||
newIntervalInput.name = 'settings_tasktimers_values';
|
||||
newIntervalInput.setAttribute('data-name', value.task);
|
||||
newIntervalInput.setAttribute('data-default', value.defaultInterval);
|
||||
newIntervalInput.type = 'number';
|
||||
newIntervalInput.placeholder = value.defaultInterval;
|
||||
newIntervalInput.min = value.minimumAllowedInterval;
|
||||
newIntervalInput.value = value.interval;
|
||||
newIntervalContent.appendChild(newIntervalInput);
|
||||
newIntervalRow.appendChild(newIntervalContent);
|
||||
|
||||
serviceTable.appendChild(newIntervalRow);
|
||||
|
||||
// allowed time periods row
|
||||
let newTableRowTime = document.createElement('tr');
|
||||
|
||||
let rowTimeContentTitle = document.createElement('td');
|
||||
rowTimeContentTitle.className = 'romcell romcell-headercell';
|
||||
rowTimeContentTitle.innerHTML = "Allowed Days:";
|
||||
newTableRowTime.appendChild(rowTimeContentTitle);
|
||||
|
||||
let rowTimeContent = document.createElement('td');
|
||||
// rowTimeContent.setAttribute('colspan', 2);
|
||||
rowTimeContent.className = 'romcell';
|
||||
let daySelector = document.createElement('select');
|
||||
daySelector.id = 'settings_alloweddays_' + value.task;
|
||||
daySelector.name = 'settings_alloweddays';
|
||||
daySelector.multiple = 'multiple';
|
||||
daySelector.setAttribute('data-default', value.defaultAllowedDays.join(","));
|
||||
daySelector.style.width = '95%';
|
||||
let days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
|
||||
for (let d = 0; d < days.length; d++) {
|
||||
let dayOpt = document.createElement('option');
|
||||
dayOpt.value = days[d];
|
||||
dayOpt.innerHTML = days[d];
|
||||
if (value.allowedDays.includes(days[d])) {
|
||||
dayOpt.selected = 'selected';
|
||||
}
|
||||
daySelector.appendChild(dayOpt);
|
||||
}
|
||||
rowTimeContent.appendChild(daySelector);
|
||||
$(daySelector).select2({
|
||||
tags: false
|
||||
});
|
||||
newTableRowTime.appendChild(rowTimeContent);
|
||||
|
||||
serviceTable.appendChild(newTableRowTime);
|
||||
|
||||
// add start and end times
|
||||
let newTableRowClock = document.createElement('tr');
|
||||
|
||||
let rowClockContentTitle = document.createElement('td');
|
||||
rowClockContentTitle.className = 'romcell romcell-headercell';
|
||||
rowClockContentTitle.innerHTML = "Time Range:";
|
||||
newTableRowClock.appendChild(rowClockContentTitle);
|
||||
|
||||
let rowClockContent = document.createElement('td');
|
||||
rowClockContent.className = 'romcell';
|
||||
// rowClockContent.setAttribute('colspan', 2);
|
||||
|
||||
rowClockContent.appendChild(generateTimeDropDowns(value.task, 'Start', value.defaultAllowedStartHours, value.defaultAllowedStartMinutes, value.allowedStartHours, value.allowedStartMinutes));
|
||||
|
||||
rowClockContentSeparator = document.createElement('span');
|
||||
rowClockContentSeparator.innerHTML = ' - ';
|
||||
rowClockContent.appendChild(rowClockContentSeparator);
|
||||
|
||||
rowClockContent.appendChild(generateTimeDropDowns(value.task, 'End', value.defaultAllowedEndHours, value.defaultAllowedEndMinutes, value.allowedEndHours, value.allowedEndMinutes));
|
||||
|
||||
newTableRowClock.appendChild(rowClockContent);
|
||||
|
||||
serviceTable.appendChild(newTableRowClock);
|
||||
|
||||
// blocks tasks
|
||||
let newTableRowBlocks = document.createElement('tr');
|
||||
|
||||
let rowBlocksContentTitle = document.createElement('td');
|
||||
rowBlocksContentTitle.className = 'romcell romcell-headercell';
|
||||
rowBlocksContentTitle.innerHTML = "Blocks:";
|
||||
newTableRowBlocks.appendChild(rowBlocksContentTitle);
|
||||
|
||||
let rowBlocksContent = document.createElement('td');
|
||||
rowBlocksContent.className = 'romcell';
|
||||
// rowBlocksContent.setAttribute('colspan', 2);
|
||||
let blocksString = "";
|
||||
for (let i = 0; i < value.blocks.length; i++) {
|
||||
if (blocksString.length > 0) { blocksString += ", "; }
|
||||
blocksString += GetTaskFriendlyName(value.blocks[i]);
|
||||
}
|
||||
if (blocksString.length == 0) { blocksString = 'None'; }
|
||||
rowBlocksContent.innerHTML = blocksString;
|
||||
newTableRowBlocks.appendChild(rowBlocksContent);
|
||||
|
||||
serviceTable.appendChild(newTableRowBlocks);
|
||||
|
||||
// blocked by tasks
|
||||
let newTableRowBlockedBy = document.createElement('tr');
|
||||
|
||||
let rowBlockedByContentTitle = document.createElement('td');
|
||||
rowBlockedByContentTitle.className = 'romcell romcell-headercell';
|
||||
rowBlockedByContentTitle.innerHTML = "Blocked By:";
|
||||
newTableRowBlockedBy.appendChild(rowBlockedByContentTitle);
|
||||
|
||||
let rowBlockedByContent = document.createElement('td');
|
||||
rowBlockedByContent.className = 'romcell';
|
||||
// rowBlockedByContent.setAttribute('colspan', 2);
|
||||
let BlockedByString = "";
|
||||
for (let i = 0; i < value.blockedBy.length; i++) {
|
||||
if (BlockedByString.length > 0) { BlockedByString += ", "; }
|
||||
BlockedByString += GetTaskFriendlyName(value.blockedBy[i]);
|
||||
}
|
||||
if (BlockedByString.length == 0) { BlockedByString = 'None'; }
|
||||
rowBlockedByContent.innerHTML = BlockedByString;
|
||||
newTableRowBlockedBy.appendChild(rowBlockedByContent);
|
||||
|
||||
serviceTable.appendChild(newTableRowBlockedBy);
|
||||
|
||||
// complete row
|
||||
targetTable.appendChild(serviceTable);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function generateTimeDropDowns(taskName, rangeName, defaultHour, defaultMinute, valueHour, valueMinute) {
|
||||
let container = document.createElement('div');
|
||||
container.style.display = 'inline';
|
||||
|
||||
let elementName = 'settings_tasktimers_time';
|
||||
|
||||
let hourSelector = document.createElement('input');
|
||||
hourSelector.id = 'settings_tasktimers_' + taskName + '_' + rangeName + '_Hour';
|
||||
hourSelector.name = elementName;
|
||||
hourSelector.setAttribute('data-name', taskName);
|
||||
hourSelector.setAttribute('type', 'number');
|
||||
hourSelector.setAttribute('min', '0');
|
||||
hourSelector.setAttribute('max', '23');
|
||||
hourSelector.setAttribute('placeholder', defaultHour);
|
||||
hourSelector.value = valueHour;
|
||||
container.appendChild(hourSelector);
|
||||
|
||||
let separator = document.createElement('span');
|
||||
separator.innerHTML = " : ";
|
||||
container.appendChild(separator);
|
||||
|
||||
let minSelector = document.createElement('input');
|
||||
minSelector.id = 'settings_tasktimers_' + taskName + '_' + rangeName + '_Minute';
|
||||
minSelector.name = elementName;
|
||||
minSelector.setAttribute('type', 'number');
|
||||
minSelector.setAttribute('min', '0');
|
||||
minSelector.setAttribute('max', '59');
|
||||
minSelector.setAttribute('placeholder', defaultMinute);
|
||||
minSelector.value = valueMinute;
|
||||
container.appendChild(minSelector);
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
function saveTaskTimers() {
|
||||
let timerValues = document.getElementsByName('settings_tasktimers_values');
|
||||
|
||||
let model = [];
|
||||
for (let i = 0; i < timerValues.length; i++) {
|
||||
let taskName = timerValues[i].getAttribute('data-name');
|
||||
let taskEnabled = document.getElementById('settings_enabled_' + taskName).checked;
|
||||
let taskIntervalObj = document.getElementById('settings_tasktimers_' + taskName);
|
||||
let taskInterval = function () { if (taskIntervalObj.value) { return taskIntervalObj.value; } else { return taskIntervalObj.getAttribute('placeholder'); } };
|
||||
let taskDaysRaw = $('#settings_alloweddays_' + taskName).select2('data');
|
||||
let taskDays = [];
|
||||
if (taskDaysRaw.length > 0) {
|
||||
for (let d = 0; d < taskDaysRaw.length; d++) {
|
||||
taskDays.push(taskDaysRaw[d].id);
|
||||
}
|
||||
} else {
|
||||
taskDays.push("Monday");
|
||||
}
|
||||
let taskStartHourObj = document.getElementById('settings_tasktimers_' + taskName + '_Start_Hour');
|
||||
let taskStartMinuteObj = document.getElementById('settings_tasktimers_' + taskName + '_Start_Minute');
|
||||
let taskEndHourObj = document.getElementById('settings_tasktimers_' + taskName + '_End_Hour');
|
||||
let taskEndMinuteObj = document.getElementById('settings_tasktimers_' + taskName + '_End_Minute');
|
||||
|
||||
let taskStartHour = function () { if (taskStartHourObj.value) { return taskStartHourObj.value; } else { return taskStartHourObj.getAttribute('placeholder'); } };
|
||||
let taskStartMinute = function () { if (taskStartMinuteObj.value) { return taskStartMinuteObj.value; } else { return taskStartMinuteObj.getAttribute('placeholder'); } };
|
||||
let taskEndHour = function () { if (taskEndHourObj.value) { return taskEndHourObj.value; } else { return taskEndHourObj.getAttribute('placeholder'); } };
|
||||
let taskEndMinute = function () { if (taskEndMinuteObj.value) { return taskEndMinuteObj.value; } else { return taskEndMinuteObj.getAttribute('placeholder'); } };
|
||||
|
||||
model.push(
|
||||
{
|
||||
"task": taskName,
|
||||
"enabled": taskEnabled,
|
||||
"interval": taskInterval(),
|
||||
"allowedDays": taskDays,
|
||||
"allowedStartHours": taskStartHour(),
|
||||
"allowedStartMinutes": taskStartMinute(),
|
||||
"allowedEndHours": taskEndHour(),
|
||||
"allowedEndMinutes": taskEndMinute()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
ajaxCall(
|
||||
'/api/v1/System/Settings/BackgroundTasks/Configuration',
|
||||
'POST',
|
||||
function (result) {
|
||||
getBackgroundTaskTimers();
|
||||
},
|
||||
function (error) {
|
||||
getBackgroundTaskTimers();
|
||||
},
|
||||
JSON.stringify(model)
|
||||
);
|
||||
}
|
||||
|
||||
function defaultTaskTimers() {
|
||||
let taskEnabled = document.getElementsByName('settings_tasktimers_enabled');
|
||||
|
||||
for (let i = 0; i < taskEnabled.length; i++) {
|
||||
taskEnabled[i].checked = true;
|
||||
}
|
||||
|
||||
let taskTimerValues = document.getElementsByName('settings_tasktimers_values');
|
||||
|
||||
for (let i = 0; i < taskTimerValues.length; i++) {
|
||||
taskTimerValues[i].value = taskTimerValues[i].getAttribute('data-default');
|
||||
}
|
||||
|
||||
let taskAllowedDays = document.getElementsByName('settings_alloweddays');
|
||||
|
||||
for (let i = 0; i < taskAllowedDays.length; i++) {
|
||||
let defaultSelections = taskAllowedDays[i].getAttribute('data-default').split(',');
|
||||
$(taskAllowedDays[i]).val(defaultSelections);
|
||||
$(taskAllowedDays[i]).trigger('change');
|
||||
}
|
||||
|
||||
let taskTimes = document.getElementsByName('settings_tasktimers_time');
|
||||
|
||||
for (let i = 0; i < taskTimes.length; i++) {
|
||||
taskTimes[i].value = taskTimes[i].getAttribute('placeholder');
|
||||
}
|
||||
|
||||
saveTaskTimers();
|
||||
}
|
@@ -2,190 +2,105 @@
|
||||
<h1 id="gametitle_label">Settings</h1>
|
||||
</div>
|
||||
|
||||
<table cellspacing="0" style="width: 100%; vertical-align: top;">
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
<h3>Metadata Sources</h3>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style="width: 25%;">
|
||||
Signature Source
|
||||
</th>
|
||||
<td>
|
||||
<input type="radio" name="settings_signaturesource" id="settings_signaturesource_local" value="LocalOnly"
|
||||
onclick="document.getElementById('settings_hasheoushost_row').style.display = 'none';">
|
||||
<label for="settings_signaturesource_local">Local Only</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<input type="radio" name="settings_signaturesource" id="settings_signaturesource_hasheous" value="Hasheous"
|
||||
onclick="document.getElementById('settings_hasheoushost_row').style.display = '';">
|
||||
<label for="settings_signaturesource_hasheous">Hasheous</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="settings_hasheoushost_row" style="display: none;">
|
||||
<th>
|
||||
Hasheous Host
|
||||
</th>
|
||||
<td>
|
||||
<input type="url" id="settings_signaturesource_hasheoushost" style="width: 90%;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<label for="settings_hasheoussubmit">Submit updates to Hasheous when fixing ROM matches</label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="checkbox" id="settings_hasheoussubmit" onchange="toggleHasheousAPIKey(this);">
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="settings_hasheousapikey_row" style="display: none;">
|
||||
<th>
|
||||
Hasheous API key
|
||||
</th>
|
||||
<td>
|
||||
<textarea id="settings_hasheousapikey" rows="2" style="width: 90%;"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
<h3>Logging</h3>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
Write logs
|
||||
</th>
|
||||
<td>
|
||||
<input type="radio" name="settings_logs_write" id="settings_logs_write_db" value="false"
|
||||
checked="checked"><label for="settings_logs_write_db"> To database only
|
||||
(default)</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<input type="radio" name="settings_logs_write" id="settings_logs_write_fs" value="true"><label
|
||||
for="settings_logs_write_fs"> To database and disk</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
Minimum log retention (days):
|
||||
</th>
|
||||
<td>
|
||||
<input type="number" min="1" id="settings_logs_retention" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
<h3>Emulator</h3>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label for="settings_emulator_debug">Enable debug mode</label></th>
|
||||
<td><input type="checkbox" name="settings_emulator" id="settings_emulator_debug" checked="checked" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="text-align: right;">
|
||||
<button id="settings_tasktimers_new" onclick="setSystemSettings();">Save</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<script type="text/javascript">
|
||||
function getSystemSettings() {
|
||||
ajaxCall(
|
||||
'/api/v1/System/Settings/System',
|
||||
'GET',
|
||||
function (result) {
|
||||
var optionToSelect = 'settings_logs_write_db';
|
||||
if (result.alwaysLogToDisk == true) {
|
||||
optionToSelect = 'settings_logs_write_fs';
|
||||
}
|
||||
document.getElementById(optionToSelect).checked = true;
|
||||
|
||||
document.getElementById('settings_logs_retention').value = result.minimumLogRetentionPeriod;
|
||||
|
||||
document.getElementById('settings_emulator_debug').checked = result.emulatorDebugMode;
|
||||
|
||||
switch (result.signatureSource.source) {
|
||||
case "LocalOnly":
|
||||
document.getElementById('settings_signaturesource_local').checked = true;
|
||||
break;
|
||||
|
||||
case "Hasheous":
|
||||
document.getElementById('settings_signaturesource_hasheous').checked = true;
|
||||
document.getElementById('settings_hasheoushost_row').style.display = '';
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
document.getElementById('settings_signaturesource_hasheoushost').value = result.signatureSource.hasheousHost;
|
||||
|
||||
let hasheousSubmitCheck = document.getElementById('settings_hasheoussubmit');
|
||||
if (result.signatureSource.hasheousSubmitFixes == true) {
|
||||
hasheousSubmitCheck.checked = true;
|
||||
}
|
||||
document.getElementById('settings_hasheousapikey').innerHTML = result.signatureSource.hasheousAPIKey;
|
||||
toggleHasheousAPIKey(hasheousSubmitCheck);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function setSystemSettings() {
|
||||
var alwaysLogToDisk = false;
|
||||
if ($("input[type='radio'][name='settings_logs_write']:checked").val() == "true") {
|
||||
alwaysLogToDisk = true;
|
||||
}
|
||||
|
||||
var retention = document.getElementById('settings_logs_retention');
|
||||
var retentionValue = 0;
|
||||
if (retention.value) {
|
||||
retentionValue = retention.value;
|
||||
} else {
|
||||
retentionValue = 7;
|
||||
}
|
||||
|
||||
var model = {
|
||||
"alwaysLogToDisk": alwaysLogToDisk,
|
||||
"minimumLogRetentionPeriod": Number(retentionValue),
|
||||
"emulatorDebugMode": document.getElementById('settings_emulator_debug').checked,
|
||||
"signatureSource": {
|
||||
"Source": $("input[type='radio'][name='settings_signaturesource']:checked").val(),
|
||||
"HasheousHost": document.getElementById('settings_signaturesource_hasheoushost').value,
|
||||
"HasheousAPIKey": document.getElementById('settings_hasheousapikey').innerHTML,
|
||||
"HasheousSubmitFixes": document.getElementById('settings_hasheoussubmit').checked
|
||||
}
|
||||
};
|
||||
|
||||
ajaxCall(
|
||||
'/api/v1/System/Settings/System',
|
||||
'POST',
|
||||
function (result) {
|
||||
getSystemSettings();
|
||||
},
|
||||
function (error) {
|
||||
getSystemSettings();
|
||||
},
|
||||
JSON.stringify(model)
|
||||
);
|
||||
}
|
||||
|
||||
function toggleHasheousAPIKey(checkbox) {
|
||||
let settings_hasheousapikey_row = document.getElementById('settings_hasheousapikey_row');
|
||||
if (checkbox.checked == true) {
|
||||
settings_hasheousapikey_row.style.display = '';
|
||||
} else {
|
||||
settings_hasheousapikey_row.style.display = 'none';
|
||||
}
|
||||
}
|
||||
<div class="section">
|
||||
<div class="section-header">Metadata Sources</div>
|
||||
<div class="section-body">
|
||||
<table>
|
||||
<tr>
|
||||
<td style="width: 25%;">
|
||||
Signature Source
|
||||
</td>
|
||||
<td>
|
||||
<input type="radio" name="settings_signaturesource" id="settings_signaturesource_local"
|
||||
value="LocalOnly"
|
||||
onclick="document.getElementById('settings_hasheoushost_row').style.display = 'none';">
|
||||
<label for="settings_signaturesource_local">Local Only</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<input type="radio" name="settings_signaturesource" id="settings_signaturesource_hasheous"
|
||||
value="Hasheous"
|
||||
onclick="document.getElementById('settings_hasheoushost_row').style.display = '';">
|
||||
<label for="settings_signaturesource_hasheous">Hasheous</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="settings_hasheoushost_row" style="display: none;">
|
||||
<td>
|
||||
Hasheous Host
|
||||
</td>
|
||||
<td>
|
||||
<input type="url" id="settings_signaturesource_hasheoushost" style="width: 90%;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="settings_hasheoussubmit">Submit updates to Hasheous when fixing ROM matches</label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" id="settings_hasheoussubmit" onchange="toggleHasheousAPIKey(this);">
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="settings_hasheousapikey_row" style="display: none;">
|
||||
<td>
|
||||
Hasheous API key
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="settings_hasheousapikey" style="width: 90%;">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="section-header">Logging</div>
|
||||
<div class="section-body">
|
||||
<table>
|
||||
<tr>
|
||||
<td style="width: 25%;">
|
||||
Write logs
|
||||
</td>
|
||||
<td>
|
||||
<input type="radio" name="settings_logs_write" id="settings_logs_write_db" value="false"
|
||||
checked="checked"><label for="settings_logs_write_db"> To database only
|
||||
(default)</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<input type="radio" name="settings_logs_write" id="settings_logs_write_fs" value="true"><label
|
||||
for="settings_logs_write_fs"> To database and disk</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 25%;">
|
||||
Minimum log retention (days):
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" min="1" id="settings_logs_retention" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="section-header">Emulator</div>
|
||||
<div class="section-body">
|
||||
<table>
|
||||
<tr>
|
||||
<td style="width: 25%;"><label for="settings_emulator_debug">Enable debug mode</label></td>
|
||||
<td><input type="checkbox" name="settings_emulator" id="settings_emulator_debug" checked="checked" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div style="text-align: right;">
|
||||
<button id="settings_tasktimers_new" onclick="setSystemSettings();">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// kick of page data load
|
||||
getSystemSettings();
|
||||
</script>
|
88
gaseous-server/wwwroot/pages/settings/settings.js
Normal file
88
gaseous-server/wwwroot/pages/settings/settings.js
Normal file
@@ -0,0 +1,88 @@
|
||||
function getSystemSettings() {
|
||||
ajaxCall(
|
||||
'/api/v1/System/Settings/System',
|
||||
'GET',
|
||||
function (result) {
|
||||
console.log(result);
|
||||
let optionToSelect = 'settings_logs_write_db';
|
||||
if (result.alwaysLogToDisk == true) {
|
||||
optionToSelect = 'settings_logs_write_fs';
|
||||
}
|
||||
document.getElementById(optionToSelect).checked = true;
|
||||
|
||||
document.getElementById('settings_logs_retention').value = result.minimumLogRetentionPeriod;
|
||||
|
||||
document.getElementById('settings_emulator_debug').checked = result.emulatorDebugMode;
|
||||
|
||||
switch (result.signatureSource.source) {
|
||||
case "LocalOnly":
|
||||
document.getElementById('settings_signaturesource_local').checked = true;
|
||||
break;
|
||||
|
||||
case "Hasheous":
|
||||
document.getElementById('settings_signaturesource_hasheous').checked = true;
|
||||
document.getElementById('settings_hasheoushost_row').style.display = '';
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
document.getElementById('settings_signaturesource_hasheoushost').value = result.signatureSource.hasheousHost;
|
||||
|
||||
let hasheousSubmitCheck = document.getElementById('settings_hasheoussubmit');
|
||||
if (result.signatureSource.hasheousSubmitFixes == true) {
|
||||
hasheousSubmitCheck.checked = true;
|
||||
}
|
||||
document.getElementById('settings_hasheousapikey').value = result.signatureSource.hasheousAPIKey;
|
||||
toggleHasheousAPIKey(hasheousSubmitCheck);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function setSystemSettings() {
|
||||
let alwaysLogToDisk = false;
|
||||
if ($("input[type='radio'][name='settings_logs_write']:checked").val() == "true") {
|
||||
alwaysLogToDisk = true;
|
||||
}
|
||||
|
||||
let retention = document.getElementById('settings_logs_retention');
|
||||
let retentionValue = 0;
|
||||
if (retention.value) {
|
||||
retentionValue = retention.value;
|
||||
} else {
|
||||
retentionValue = 7;
|
||||
}
|
||||
|
||||
let model = {
|
||||
"alwaysLogToDisk": alwaysLogToDisk,
|
||||
"minimumLogRetentionPeriod": Number(retentionValue),
|
||||
"emulatorDebugMode": document.getElementById('settings_emulator_debug').checked,
|
||||
"signatureSource": {
|
||||
"Source": $("input[type='radio'][name='settings_signaturesource']:checked").val(),
|
||||
"HasheousHost": document.getElementById('settings_signaturesource_hasheoushost').value,
|
||||
"HasheousAPIKey": document.getElementById('settings_hasheousapikey').value,
|
||||
"HasheousSubmitFixes": document.getElementById('settings_hasheoussubmit').checked
|
||||
}
|
||||
};
|
||||
console.log(model);
|
||||
|
||||
ajaxCall(
|
||||
'/api/v1/System/Settings/System',
|
||||
'POST',
|
||||
function (result) {
|
||||
getSystemSettings();
|
||||
},
|
||||
function (error) {
|
||||
getSystemSettings();
|
||||
},
|
||||
JSON.stringify(model)
|
||||
);
|
||||
}
|
||||
|
||||
function toggleHasheousAPIKey(checkbox) {
|
||||
let settings_hasheousapikey_row = document.getElementById('settings_hasheousapikey_row');
|
||||
if (checkbox.checked == true) {
|
||||
settings_hasheousapikey_row.style.display = '';
|
||||
} else {
|
||||
settings_hasheousapikey_row.style.display = 'none';
|
||||
}
|
||||
}
|
@@ -2,271 +2,50 @@
|
||||
<h1 id="gametitle_label">System</h1>
|
||||
</div>
|
||||
|
||||
<h3>Background Tasks</h3>
|
||||
<div id="system_tasks"></div>
|
||||
|
||||
<h3>Usage</h3>
|
||||
<p><strong>Disk</strong></p>
|
||||
<div id="system_disks"></div>
|
||||
<p><strong>Library</strong></p>
|
||||
<div>
|
||||
<table cellspacing="0" style="width: 100%;">
|
||||
<tr>
|
||||
<td id="system_platforms"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="system_platforms_legend"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="section">
|
||||
<div class="section-header">Background Tasks</div>
|
||||
<div id="system_tasks" class="section-body"></div>
|
||||
</div>
|
||||
<p><strong>Database</strong></p>
|
||||
<div id="system_database"></div>
|
||||
|
||||
<h3>Local Database Signatures</h3>
|
||||
<div id="system_signatures"></div>
|
||||
<div class="section">
|
||||
<div class="section-header">Disk Usage</div>
|
||||
<div class="section-body">
|
||||
<div id="system_disks"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<div class="section-header">Library</div>
|
||||
<div class="section-body">
|
||||
<table cellspacing="0" style="width: 100%;">
|
||||
<tr>
|
||||
<td id="system_platforms"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="system_platforms_legend"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<div class="section-header">Database</div>
|
||||
<div class="section-body">
|
||||
<div id="system_database"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<div class="section-header">Local Database Signatures</div>
|
||||
<div class="section-body">
|
||||
<div id="system_signatures"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function SystemLoadStatus() {
|
||||
ajaxCall('/api/v1.1/BackgroundTasks', 'GET', function (result) {
|
||||
var newTable = document.createElement('table');
|
||||
newTable.className = 'romtable';
|
||||
newTable.setAttribute('cellspacing', 0);
|
||||
newTable.appendChild(createTableRow(true, ['Task', 'Status', 'Interval<br/>(minutes)', 'Last Run Duration<br />(hh:mm:ss)', '', 'Last Run Start', 'Next Run Start', '']));
|
||||
|
||||
if (result) {
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
if (result[i].itemState != "Disabled") {
|
||||
var itemTypeName = GetTaskFriendlyName(result[i].itemType, result[i].options);
|
||||
|
||||
var itemStateName;
|
||||
var itemLastStart;
|
||||
|
||||
var hasError = "";
|
||||
if (result[i].hasErrors) {
|
||||
if (result[i].hasErrors.errorType != null) {
|
||||
hasError = " (" + result[i].hasErrors.errorType + ")";
|
||||
}
|
||||
}
|
||||
|
||||
if (result[i].isBlocked == false) {
|
||||
switch (result[i].itemState) {
|
||||
case 'NeverStarted':
|
||||
itemStateName = "Never started";
|
||||
itemLastStart = '-';
|
||||
break;
|
||||
case 'Stopped':
|
||||
itemStateName = "Stopped";
|
||||
itemLastStart = moment(result[i].lastRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||
break;
|
||||
case 'Running':
|
||||
var progressPercent = "";
|
||||
if (result[i].currentStateProgress) {
|
||||
progressPercent = " (" + result[i].currentStateProgress + ")";
|
||||
}
|
||||
itemStateName = "Running" + progressPercent;
|
||||
itemLastStart = moment(result[i].lastRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||
break;
|
||||
default:
|
||||
itemStateName = "Unknown status";
|
||||
itemLastStart = moment(result[i].lastRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
itemStateName = "Blocked";
|
||||
itemLastStart = moment(result[i].lastRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||
}
|
||||
|
||||
itemStateName += hasError;
|
||||
|
||||
var itemInterval = result[i].interval;
|
||||
var nextRunTime = moment(result[i].nextRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||
var startButton = '';
|
||||
if (userProfile.roles.includes("Admin")) {
|
||||
if (result[i].allowManualStart == true && !["Running"].includes(result[i].itemState) && result[i].isBlocked == false) {
|
||||
startButton = "<span id='startProcess' class='romstart' onclick='StartProcess(\"" + result[i].itemType + "\");'>Start</span>";
|
||||
}
|
||||
}
|
||||
|
||||
if (result[i].allowManualStart == false && result[i].removeWhenStopped == true) {
|
||||
itemInterval = '';
|
||||
nextRunTime = '';
|
||||
}
|
||||
|
||||
var logLink = '';
|
||||
if (result[i].correlationId) {
|
||||
logLink = '<a href="/index.html?page=settings&sub=logs&correlationid=' + result[i].correlationId + '" class="romlink">View Log</a>';
|
||||
}
|
||||
|
||||
var newRow = [
|
||||
itemTypeName,
|
||||
itemStateName,
|
||||
itemInterval,
|
||||
new Date(result[i].lastRunDuration * 1000).toISOString().slice(11, 19),
|
||||
logLink,
|
||||
itemLastStart,
|
||||
nextRunTime,
|
||||
startButton
|
||||
];
|
||||
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var targetDiv = document.getElementById('system_tasks');
|
||||
targetDiv.innerHTML = '';
|
||||
targetDiv.appendChild(newTable);
|
||||
});
|
||||
}
|
||||
|
||||
function SystemLoadSystemStatus() {
|
||||
ajaxCall('/api/v1.1/System', 'GET', function (result) {
|
||||
if (result) {
|
||||
var totalLibrarySpace = 0;
|
||||
|
||||
// disks
|
||||
var newTable = document.createElement('table');
|
||||
newTable.className = 'romtable';
|
||||
newTable.setAttribute('cellspacing', 0);
|
||||
newTable.appendChild(createTableRow(true, ['Path', 'Library Size <div id="disk_LibSize" style="width: 10px; height: 10px; background-color: green;"></div>', 'Other <div id="disk_OtherSize" style="width: 10px; height: 10px; background-color: lightgreen;"></div>', 'Total Size <div id="disk_FreeSize" style="width: 10px; height: 10px; background-color: lightgray;"></div>']));
|
||||
|
||||
for (var i = 0; i < result.paths.length; i++) {
|
||||
var spaceUsedByLibrary = result.paths[i].spaceUsed;
|
||||
totalLibrarySpace += spaceUsedByLibrary;
|
||||
var spaceUsedByOthers = result.paths[i].totalSpace - result.paths[i].spaceAvailable;
|
||||
|
||||
var newRow = [
|
||||
result.paths[i].libraryPath,
|
||||
formatBytes(spaceUsedByLibrary),
|
||||
formatBytes(spaceUsedByOthers),
|
||||
formatBytes(result.paths[i].totalSpace)
|
||||
];
|
||||
|
||||
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
||||
|
||||
var spaceRow = document.createElement('tr');
|
||||
var spaceCell = document.createElement('td');
|
||||
spaceCell.setAttribute('colspan', 4);
|
||||
spaceCell.appendChild(BuildSpaceBar(spaceUsedByLibrary, spaceUsedByOthers, result.paths[i].totalSpace));
|
||||
spaceRow.appendChild(spaceCell);
|
||||
newTable.appendChild(spaceRow);
|
||||
}
|
||||
|
||||
var targetDiv = document.getElementById('system_disks');
|
||||
targetDiv.innerHTML = '';
|
||||
targetDiv.appendChild(newTable);
|
||||
|
||||
BuildLibraryStatisticsBar(document.getElementById('system_platforms'), document.getElementById('system_platforms_legend'), result.platformStatistics, totalLibrarySpace);
|
||||
|
||||
// database
|
||||
var newDbTable = document.createElement('table');
|
||||
newDbTable.className = 'romtable';
|
||||
newDbTable.setAttribute('cellspacing', 0);
|
||||
newDbTable.appendChild(createTableRow(false, ['Database Size', formatBytes(result.databaseSize)]));
|
||||
|
||||
var targetDbDiv = document.getElementById('system_database');
|
||||
targetDbDiv.innerHTML = '';
|
||||
targetDbDiv.appendChild(newDbTable);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function BuildSpaceBar(LibrarySize, OtherSize, TotalSize) {
|
||||
var newTable = document.createElement('table');
|
||||
newTable.setAttribute('cellspacing', 0);
|
||||
newTable.setAttribute('style', 'width: 100%; height: 10px;');
|
||||
|
||||
var newRow = document.createElement('tr');
|
||||
|
||||
var LibrarySizePercent = Math.floor(LibrarySize / TotalSize * 100);
|
||||
var OtherSizePercent = Math.floor(OtherSize / TotalSize * 100);
|
||||
var FreeSizePercent = Math.floor((LibrarySize + OtherSize) / TotalSize * 100);
|
||||
|
||||
var LibraryCell = document.createElement('td');
|
||||
LibraryCell.setAttribute('style', 'width: ' + LibrarySizePercent + '%; background-color: green;');
|
||||
|
||||
var OtherCell = document.createElement('td');
|
||||
OtherCell.setAttribute('style', 'width: ' + OtherSizePercent + '%; background-color: lightgreen;');
|
||||
|
||||
var FreeCell = document.createElement('td');
|
||||
FreeCell.setAttribute('style', 'width: ' + FreeSizePercent + '%; background-color: lightgray;');
|
||||
|
||||
newRow.appendChild(LibraryCell);
|
||||
newRow.appendChild(OtherCell);
|
||||
newRow.appendChild(FreeCell);
|
||||
|
||||
newTable.appendChild(newRow);
|
||||
|
||||
return newTable;
|
||||
}
|
||||
|
||||
function BuildLibraryStatisticsBar(TargetObject, TargetObjectLegend, LibraryStatistics, LibrarySize) {
|
||||
TargetObject.innerHTML = '';
|
||||
TargetObjectLegend.innerHTML = '';
|
||||
|
||||
var newTable = document.createElement('table');
|
||||
newTable.setAttribute('cellspacing', 0);
|
||||
newTable.setAttribute('style', 'width: 100%; height: 10px;');
|
||||
|
||||
var newRow = document.createElement('tr');
|
||||
|
||||
for (var i = 0; i < LibraryStatistics.length; i++) {
|
||||
var platformSizePercent = LibraryStatistics[i].totalSize / LibrarySize * 100;
|
||||
var platformSizeColour = intToRGB(hashCode(LibraryStatistics[i].platform));
|
||||
var newCell = document.createElement('td');
|
||||
newCell.setAttribute('style', 'min-width: 2px; width: ' + platformSizePercent + '%; background-color: #' + platformSizeColour);
|
||||
newRow.appendChild(newCell);
|
||||
|
||||
var legend = document.createElement('div');
|
||||
legend.className = 'legend_box';
|
||||
|
||||
var legendColour = document.createElement('div');
|
||||
legendColour.className = 'legend_colour';
|
||||
legendColour.setAttribute('style', 'background-color: #' + platformSizeColour + ';');
|
||||
|
||||
var legendLabel = document.createElement('div');
|
||||
legendLabel.className = 'legend_label';
|
||||
legendLabel.innerHTML = LibraryStatistics[i].platform + '<br />' + formatBytes(LibraryStatistics[i].totalSize) + '<br />Images: ' + LibraryStatistics[i].romCount;
|
||||
|
||||
legend.appendChild(legendColour);
|
||||
legend.appendChild(legendLabel);
|
||||
TargetObjectLegend.appendChild(legend);
|
||||
}
|
||||
|
||||
newTable.appendChild(newRow);
|
||||
TargetObject.appendChild(newTable);
|
||||
}
|
||||
|
||||
function SystemSignaturesStatus() {
|
||||
ajaxCall('/api/v1.1/Signatures/Status', 'GET', function (result) {
|
||||
var newTable = document.createElement('table');
|
||||
newTable.className = 'romtable';
|
||||
newTable.setAttribute('cellspacing', 0);
|
||||
newTable.appendChild(createTableRow(true, ['Sources', 'Platforms', 'Games', 'ROMs']));
|
||||
|
||||
if (result) {
|
||||
var newRow = [
|
||||
result.sources,
|
||||
result.platforms,
|
||||
result.games,
|
||||
result.roms
|
||||
];
|
||||
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
||||
}
|
||||
|
||||
var targetDiv = document.getElementById('system_signatures');
|
||||
targetDiv.innerHTML = '';
|
||||
targetDiv.appendChild(newTable);
|
||||
});
|
||||
}
|
||||
|
||||
function StartProcess(itemType) {
|
||||
ajaxCall('/api/v1.1/BackgroundTasks/' + itemType + '?ForceRun=true', 'GET', function (result) {
|
||||
SystemLoadStatus();
|
||||
});
|
||||
}
|
||||
|
||||
// Load the system status
|
||||
SystemLoadStatus();
|
||||
setInterval(SystemLoadStatus, 3000);
|
||||
setInterval(SystemLoadStatus, 2000);
|
||||
SystemLoadSystemStatus();
|
||||
setInterval(SystemLoadSystemStatus, 60000);
|
||||
SystemSignaturesStatus();
|
||||
|
297
gaseous-server/wwwroot/pages/settings/system.js
Normal file
297
gaseous-server/wwwroot/pages/settings/system.js
Normal file
@@ -0,0 +1,297 @@
|
||||
function SystemLoadStatus() {
|
||||
ajaxCall('/api/v1.1/BackgroundTasks', 'GET', function (result) {
|
||||
let newTable = document.createElement('table');
|
||||
newTable.className = 'romtable';
|
||||
newTable.setAttribute('cellspacing', 0);
|
||||
newTable.appendChild(createTableRow(true, ['Task', 'Status', '', '', 'Interval<br/>(minutes)', 'Last Run Duration<br />(hh:mm:ss)', 'Last Run Start', 'Next Run Start', '']));
|
||||
|
||||
if (result) {
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
if (result[i].itemState != "Disabled") {
|
||||
let itemTypeName = GetTaskFriendlyName(result[i].itemType, result[i].options);
|
||||
|
||||
let itemStateName;
|
||||
let itemLastStart;
|
||||
|
||||
let hasError = "";
|
||||
if (result[i].hasErrors) {
|
||||
if (result[i].hasErrors.errorType != null) {
|
||||
// hasError = " (" + result[i].hasErrors.errorType + ")";
|
||||
hasError = "<img src='/images/" + result[i].hasErrors.errorType + ".svg' class='banner_button_image' style='padding-top: 5px;' title='" + result[i].hasErrors.errorType + "'>";
|
||||
}
|
||||
}
|
||||
|
||||
if (result[i].isBlocked == false) {
|
||||
if (result[i].force == true && result[i].itemState != "Running") {
|
||||
itemStateName = "<div>Pending </div><div><progress></progress></div>";
|
||||
itemLastStart = '-';
|
||||
} else {
|
||||
switch (result[i].itemState) {
|
||||
case 'NeverStarted':
|
||||
itemStateName = "Never started";
|
||||
itemLastStart = moment(result[i].lastRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||
break;
|
||||
case 'Stopped':
|
||||
itemStateName = "Stopped";
|
||||
itemLastStart = moment(result[i].lastRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||
break;
|
||||
case 'Running':
|
||||
itemStateName = "Running";
|
||||
if (result[i].currentStateProgress) {
|
||||
if (result[i].currentStateProgress.includes(" of ")) {
|
||||
let progressParts = result[i].currentStateProgress.split(" of ");
|
||||
itemStateName = "<div>Running " + result[i].currentStateProgress + "</div><div><progress value=\"" + progressParts[0] + "\" max=\"" + progressParts[1] + "\">" + result[i].currentStateProgress + "</progress></div>";
|
||||
} else {
|
||||
itemStateName = "Running (" + result[i].currentStateProgress + ")";
|
||||
}
|
||||
}
|
||||
itemLastStart = moment(result[i].lastRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||
break;
|
||||
default:
|
||||
itemStateName = "Unknown status";
|
||||
itemLastStart = moment(result[i].lastRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
itemStateName = "Blocked";
|
||||
itemLastStart = moment(result[i].lastRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||
}
|
||||
|
||||
let itemInterval = result[i].interval;
|
||||
let nextRunTime = moment(result[i].nextRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||
let startButton = '';
|
||||
if (userProfile.roles.includes("Admin")) {
|
||||
if (result[i].force == false) {
|
||||
if (result[i].allowManualStart == true && !["Running"].includes(result[i].itemState) && result[i].isBlocked == false) {
|
||||
startButton = "<img id='startProcess' class='taskstart' src='/images/start-task.svg' onclick='StartProcess(\"" + result[i].itemType + "\");' title='Start'>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result[i].allowManualStart == false && result[i].removeWhenStopped == true) {
|
||||
itemInterval = '';
|
||||
nextRunTime = '';
|
||||
}
|
||||
|
||||
let logLink = '';
|
||||
if (result[i].correlationId) {
|
||||
logLink = '<a href="/index.html?page=settings&sub=logs&correlationid=' + result[i].correlationId + '" class="romlink">Logs</a>';
|
||||
}
|
||||
|
||||
let newRow = [
|
||||
itemTypeName,
|
||||
itemStateName,
|
||||
hasError,
|
||||
logLink,
|
||||
itemInterval,
|
||||
new Date(result[i].lastRunDuration * 1000).toISOString().slice(11, 19),
|
||||
itemLastStart,
|
||||
nextRunTime,
|
||||
startButton
|
||||
];
|
||||
newTable.appendChild(createTableRow(false, newRow, 'romrow taskrow', 'romcell'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let targetDiv = document.getElementById('system_tasks');
|
||||
targetDiv.innerHTML = '';
|
||||
targetDiv.appendChild(newTable);
|
||||
});
|
||||
}
|
||||
|
||||
function SystemLoadSystemStatus() {
|
||||
ajaxCall('/api/v1.1/System', 'GET', function (result) {
|
||||
if (result) {
|
||||
let totalLibrarySpace = 0;
|
||||
|
||||
// disks
|
||||
let newTable = document.createElement('table');
|
||||
newTable.className = 'romtable';
|
||||
newTable.setAttribute('cellspacing', 0);
|
||||
newTable.appendChild(createTableRow(true, ['Path', 'Library Size <div id="disk_LibSize" style="width: 10px; height: 10px; background-color: green;"></div>', 'Other <div id="disk_OtherSize" style="width: 10px; height: 10px; background-color: lightgreen;"></div>', 'Total Size <div id="disk_FreeSize" style="width: 10px; height: 10px; background-color: lightgray;"></div>']));
|
||||
|
||||
for (let i = 0; i < result.paths.length; i++) {
|
||||
let spaceUsedByLibrary = result.paths[i].spaceUsed;
|
||||
totalLibrarySpace += spaceUsedByLibrary;
|
||||
let spaceUsedByOthers = result.paths[i].totalSpace - result.paths[i].spaceAvailable;
|
||||
|
||||
let libraryRow = document.createElement('tbody');
|
||||
libraryRow.className = 'romrow';
|
||||
|
||||
let titleRow = document.createElement('tr');
|
||||
let titleCell = document.createElement('td');
|
||||
titleCell.setAttribute('colspan', 4);
|
||||
titleCell.innerHTML = '<strong>' + result.paths[i].name + '</strong>';
|
||||
titleCell.className = 'romcell';
|
||||
titleRow.appendChild(titleCell);
|
||||
libraryRow.appendChild(titleRow);
|
||||
|
||||
let newRow = [
|
||||
result.paths[i].libraryPath,
|
||||
formatBytes(spaceUsedByLibrary),
|
||||
formatBytes(spaceUsedByOthers),
|
||||
formatBytes(result.paths[i].totalSpace)
|
||||
];
|
||||
|
||||
libraryRow.appendChild(createTableRow(false, newRow, '', 'romcell'));
|
||||
|
||||
let spaceRow = document.createElement('tr');
|
||||
let spaceCell = document.createElement('td');
|
||||
spaceCell.setAttribute('colspan', 4);
|
||||
spaceCell.appendChild(BuildSpaceBar(spaceUsedByLibrary, spaceUsedByOthers, result.paths[i].totalSpace));
|
||||
spaceRow.appendChild(spaceCell);
|
||||
libraryRow.appendChild(spaceRow);
|
||||
|
||||
newTable.appendChild(libraryRow);
|
||||
}
|
||||
|
||||
let targetDiv = document.getElementById('system_disks');
|
||||
targetDiv.innerHTML = '';
|
||||
targetDiv.appendChild(newTable);
|
||||
|
||||
BuildLibraryStatisticsBar(document.getElementById('system_platforms'), document.getElementById('system_platforms_legend'), result.platformStatistics, totalLibrarySpace);
|
||||
|
||||
// database
|
||||
let newDbTable = document.createElement('table');
|
||||
newDbTable.className = 'romtable';
|
||||
newDbTable.setAttribute('cellspacing', 0);
|
||||
newDbTable.appendChild(createTableRow(false, ['Database Size', formatBytes(result.databaseSize)]));
|
||||
|
||||
let targetDbDiv = document.getElementById('system_database');
|
||||
targetDbDiv.innerHTML = '';
|
||||
targetDbDiv.appendChild(newDbTable);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function BuildSpaceBar(LibrarySize, OtherSize, TotalSize) {
|
||||
let newTable = document.createElement('table');
|
||||
newTable.setAttribute('cellspacing', 0);
|
||||
newTable.setAttribute('style', 'width: 100%; height: 10px;');
|
||||
|
||||
let newRow = document.createElement('tr');
|
||||
|
||||
let LibrarySizePercent = Math.floor(LibrarySize / TotalSize * 100);
|
||||
let OtherSizePercent = Math.floor(OtherSize / TotalSize * 100);
|
||||
let FreeSizePercent = Math.floor((LibrarySize + OtherSize) / TotalSize * 100);
|
||||
|
||||
let LibraryCell = document.createElement('td');
|
||||
LibraryCell.setAttribute('style', 'width: ' + LibrarySizePercent + '%; background-color: green;');
|
||||
|
||||
let OtherCell = document.createElement('td');
|
||||
OtherCell.setAttribute('style', 'width: ' + OtherSizePercent + '%; background-color: lightgreen;');
|
||||
|
||||
let FreeCell = document.createElement('td');
|
||||
FreeCell.setAttribute('style', 'width: ' + FreeSizePercent + '%; background-color: lightgray;');
|
||||
|
||||
newRow.appendChild(LibraryCell);
|
||||
newRow.appendChild(OtherCell);
|
||||
newRow.appendChild(FreeCell);
|
||||
|
||||
newTable.appendChild(newRow);
|
||||
|
||||
return newTable;
|
||||
}
|
||||
|
||||
function BuildLibraryStatisticsBar(TargetObject, TargetObjectLegend, LibraryStatistics, LibrarySize) {
|
||||
TargetObject.innerHTML = '';
|
||||
TargetObjectLegend.innerHTML = '';
|
||||
|
||||
let newTable = document.createElement('div');
|
||||
newTable.setAttribute('cellspacing', 0);
|
||||
newTable.setAttribute('style', 'width: 100%; height: 10px;');
|
||||
|
||||
let newRow = document.createElement('div');
|
||||
newRow.setAttribute('style', 'display: flex; width: 100%;');
|
||||
|
||||
for (let i = 0; i < LibraryStatistics.length; i++) {
|
||||
let platformSizePercent = LibraryStatistics[i].totalSize / LibrarySize * 100;
|
||||
let platformSizeColour = intToRGB(hashCode(LibraryStatistics[i].platform));
|
||||
let newCell = document.createElement('div');
|
||||
let segmentId = 'platform_' + LibraryStatistics[i].platform;
|
||||
newCell.id = segmentId;
|
||||
newCell.setAttribute('style', 'display: inline; height: 10px; min-width: 1px; width: ' + platformSizePercent + '%; background-color: #' + platformSizeColour);
|
||||
// newCell.innerHTML = ' ';
|
||||
newRow.appendChild(newCell);
|
||||
|
||||
let legend = document.createElement('div');
|
||||
legend.id = 'legend_' + LibraryStatistics[i].platform;
|
||||
legend.className = 'legend_box';
|
||||
|
||||
let legendColour = document.createElement('div');
|
||||
let colourId = 'colour_' + LibraryStatistics[i].platform;
|
||||
legendColour.id = colourId;
|
||||
legendColour.className = 'legend_colour';
|
||||
legendColour.setAttribute('style', 'background-color: #' + platformSizeColour + ';');
|
||||
|
||||
let legendLabel = document.createElement('div');
|
||||
legendLabel.className = 'legend_label';
|
||||
legendLabel.innerHTML = '<strong>' + LibraryStatistics[i].platform + '</strong><br />' + formatBytes(LibraryStatistics[i].totalSize) + '<br />ROMs: ' + LibraryStatistics[i].romCount;
|
||||
|
||||
// event listeners
|
||||
legend.addEventListener('mouseenter', function () {
|
||||
let segment = document.getElementById(segmentId);
|
||||
segment.style.outline = '2px solid #' + platformSizeColour;
|
||||
segment.style.outlineOffset = '0px';
|
||||
segment.style.zIndex = '1';
|
||||
segment.style.boxShadow = '0px 0px 10px 0px #' + platformSizeColour;
|
||||
|
||||
let legendColour = document.getElementById(colourId);
|
||||
legendColour.style.outline = '2px solid #' + platformSizeColour;
|
||||
legendColour.style.outlineOffset = '0px';
|
||||
legendColour.style.zIndex = '1';
|
||||
legendColour.style.boxShadow = '0px 0px 10px 0px #' + platformSizeColour;
|
||||
});
|
||||
legend.addEventListener('mouseleave', function () {
|
||||
let segment = document.getElementById(segmentId);
|
||||
segment.style.outline = 'none';
|
||||
segment.style.outlineOffset = '0px';
|
||||
segment.style.zIndex = '0';
|
||||
segment.style.boxShadow = 'none';
|
||||
|
||||
let legendColour = document.getElementById(colourId);
|
||||
legendColour.style.outline = 'none';
|
||||
legendColour.style.outlineOffset = '0px';
|
||||
legendColour.style.zIndex = '0';
|
||||
legendColour.style.boxShadow = 'none';
|
||||
});
|
||||
|
||||
legend.appendChild(legendColour);
|
||||
legend.appendChild(legendLabel);
|
||||
TargetObjectLegend.appendChild(legend);
|
||||
}
|
||||
|
||||
newTable.appendChild(newRow);
|
||||
TargetObject.appendChild(newTable);
|
||||
}
|
||||
|
||||
function SystemSignaturesStatus() {
|
||||
ajaxCall('/api/v1.1/Signatures/Status', 'GET', function (result) {
|
||||
let newTable = document.createElement('table');
|
||||
newTable.className = 'romtable';
|
||||
newTable.setAttribute('cellspacing', 0);
|
||||
newTable.appendChild(createTableRow(true, ['Sources', 'Platforms', 'Games', 'ROMs']));
|
||||
|
||||
if (result) {
|
||||
let newRow = [
|
||||
result.sources,
|
||||
result.platforms,
|
||||
result.games,
|
||||
result.roms
|
||||
];
|
||||
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
||||
}
|
||||
|
||||
let targetDiv = document.getElementById('system_signatures');
|
||||
targetDiv.innerHTML = '';
|
||||
targetDiv.appendChild(newTable);
|
||||
});
|
||||
}
|
||||
|
||||
function StartProcess(itemType) {
|
||||
ajaxCall('/api/v1.1/BackgroundTasks/' + itemType + '?ForceRun=true', 'GET', function (result) {
|
||||
SystemLoadStatus();
|
||||
});
|
||||
}
|
@@ -2,100 +2,19 @@
|
||||
<h1 id="gametitle_label">Users</h1>
|
||||
</div>
|
||||
|
||||
<button id="settings_users_new" value="New User" style="float: right;" onclick="showSubDialog('settingsusernew');">New User</button>
|
||||
|
||||
<div id="settings_users_table_container">
|
||||
<div class="section">
|
||||
<div class="section-body">
|
||||
<div id="settings_users_table_container">
|
||||
|
||||
</div>
|
||||
<div style="text-align: right;"><button id="settings_users_new" value="New User">New
|
||||
User</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function GetUsers() {
|
||||
var targetDiv = document.getElementById('settings_users_table_container');
|
||||
targetDiv.innerHTML = '';
|
||||
|
||||
ajaxCall(
|
||||
'/api/v1.1/Account/Users',
|
||||
'GET',
|
||||
function(result) {
|
||||
var newTable = document.createElement('table');
|
||||
newTable.className = 'romtable';
|
||||
newTable.style.width = '100%';
|
||||
newTable.cellSpacing = 0;
|
||||
|
||||
newTable.appendChild(
|
||||
createTableRow(
|
||||
true,
|
||||
[
|
||||
'',
|
||||
'Email',
|
||||
'Role',
|
||||
'Age Restriction',
|
||||
''
|
||||
],
|
||||
'',
|
||||
''
|
||||
)
|
||||
);
|
||||
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
var userAvatar = document.createElement('img');
|
||||
userAvatar.className = "user_list_icon";
|
||||
if (result[i].avatar != "00000000-0000-0000-0000-000000000000") {
|
||||
userAvatar.setAttribute("src", "/api/v1.1/Account/Avatar/" + result[i].avatar + ".jpg");
|
||||
} else {
|
||||
userAvatar.setAttribute("src", "/images/user.svg");
|
||||
userAvatar.classList.add("user_list_icon_reversed");
|
||||
}
|
||||
|
||||
var roleDiv = document.createElement('div');
|
||||
|
||||
var roleItem = CreateBadge(result[i].highestRole);
|
||||
roleDiv.appendChild(roleItem);
|
||||
|
||||
var ageRestrictionPolicyDescription = document.createElement('div');
|
||||
if (result[i].securityProfile != null) {
|
||||
if (result[i].securityProfile.ageRestrictionPolicy != null) {
|
||||
var IncludeUnratedText = '';
|
||||
if (result[i].securityProfile.ageRestrictionPolicy.includeUnrated == true) {
|
||||
IncludeUnratedText = " + Unclassified titles";
|
||||
}
|
||||
|
||||
var restrictionText = result[i].securityProfile.ageRestrictionPolicy.maximumAgeRestriction + IncludeUnratedText;
|
||||
|
||||
ageRestrictionPolicyDescription = CreateBadge(restrictionText);
|
||||
}
|
||||
}
|
||||
|
||||
var editButton = '';
|
||||
|
||||
var deleteButton = '';
|
||||
|
||||
if (userProfile.userId != result[i].id) {
|
||||
editButton = '<a href="#" onclick="showDialog(\'settingsuseredit\', \'' + result[i].id + '\');" class="romlink"><img src="/images/edit.svg" class="banner_button_image" alt="Edit" title="Edit" /></a>';
|
||||
|
||||
deleteButton = '<a href="#" onclick="showSubDialog(\'settingsuserdelete\', \'' + result[i].id + '\');" class="romlink"><img src="/images/delete.svg" class="banner_button_image" alt="Delete" title="Delete" /></a>';
|
||||
}
|
||||
|
||||
newTable.appendChild(
|
||||
createTableRow(
|
||||
false,
|
||||
[
|
||||
userAvatar,
|
||||
result[i].emailAddress,
|
||||
roleDiv,
|
||||
ageRestrictionPolicyDescription,
|
||||
'<div style="text-align: right;">' + editButton + deleteButton + '</div>'
|
||||
],
|
||||
'romrow',
|
||||
'romcell'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
targetDiv.appendChild(newTable);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Load the users table
|
||||
SetupPage();
|
||||
GetUsers();
|
||||
</script>
|
590
gaseous-server/wwwroot/pages/settings/users.js
Normal file
590
gaseous-server/wwwroot/pages/settings/users.js
Normal file
@@ -0,0 +1,590 @@
|
||||
function SetupPage() {
|
||||
// set up new user button
|
||||
let newUserButton = document.getElementById('settings_users_new');
|
||||
newUserButton.addEventListener('click', function () {
|
||||
let userNew = new UserNew();
|
||||
userNew.open();
|
||||
});
|
||||
}
|
||||
|
||||
function GetUsers() {
|
||||
console.log("Loading users...");
|
||||
let targetDiv = document.getElementById('settings_users_table_container');
|
||||
targetDiv.innerHTML = '';
|
||||
|
||||
ajaxCall(
|
||||
'/api/v1.1/Account/Users',
|
||||
'GET',
|
||||
function (result) {
|
||||
let newTable = document.createElement('table');
|
||||
newTable.className = 'romtable';
|
||||
newTable.style.width = '100%';
|
||||
newTable.cellSpacing = 0;
|
||||
|
||||
newTable.appendChild(
|
||||
createTableRow(
|
||||
true,
|
||||
[
|
||||
'',
|
||||
'Email',
|
||||
'Role',
|
||||
'Age Restriction',
|
||||
''
|
||||
],
|
||||
'',
|
||||
''
|
||||
)
|
||||
);
|
||||
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
let userAvatar = new Avatar(result[i].profileId, 32, 32, true);
|
||||
userAvatar.classList.add("user_list_icon");
|
||||
|
||||
let roleDiv = document.createElement('div');
|
||||
|
||||
let roleItem = CreateBadge(result[i].highestRole);
|
||||
roleDiv.appendChild(roleItem);
|
||||
|
||||
let ageRestrictionPolicyDescription = document.createElement('div');
|
||||
if (result[i].securityProfile != null) {
|
||||
if (result[i].securityProfile.ageRestrictionPolicy != null) {
|
||||
let IncludeUnratedText = '';
|
||||
if (result[i].securityProfile.ageRestrictionPolicy.includeUnrated == true) {
|
||||
IncludeUnratedText = " + Unclassified titles";
|
||||
}
|
||||
|
||||
let restrictionText = result[i].securityProfile.ageRestrictionPolicy.maximumAgeRestriction + IncludeUnratedText;
|
||||
|
||||
ageRestrictionPolicyDescription = CreateBadge(restrictionText);
|
||||
}
|
||||
}
|
||||
|
||||
let controls = document.createElement('div');
|
||||
controls.style.textAlign = 'right';
|
||||
|
||||
let editButton = '';
|
||||
let deleteButton = '';
|
||||
|
||||
if (userProfile.userId != result[i].id) {
|
||||
editButton = document.createElement('a');
|
||||
editButton.href = '#';
|
||||
editButton.addEventListener('click', () => {
|
||||
// showDialog('settingsuseredit', result[i].id);
|
||||
let userEdit = new UserEdit(result[i].id, GetUsers);
|
||||
userEdit.open();
|
||||
});
|
||||
editButton.classList.add('romlink');
|
||||
|
||||
let editButtonImage = document.createElement('img');
|
||||
editButtonImage.src = '/images/edit.svg';
|
||||
editButtonImage.classList.add('banner_button_image');
|
||||
editButtonImage.alt = 'Edit';
|
||||
editButtonImage.title = 'Edit';
|
||||
editButton.appendChild(editButtonImage);
|
||||
|
||||
controls.appendChild(editButton);
|
||||
|
||||
deleteButton = document.createElement('a');
|
||||
deleteButton.href = '#';
|
||||
deleteButton.addEventListener('click', () => {
|
||||
let warningDialog = new MessageBox("Delete User", "Are you sure you want to delete this user?<br /><br /><strong>Warning</strong>: This cannot be undone!");
|
||||
warningDialog.addButton(new ModalButton("OK", 2, warningDialog, async (callingObject) => {
|
||||
fetch("/api/v1.1/Account/Users/" + result[i].id, {
|
||||
method: 'DELETE'
|
||||
}).then(async response => {
|
||||
if (response.ok) {
|
||||
GetUsers();
|
||||
callingObject.msgDialog.close();
|
||||
} else {
|
||||
let result = await response.json();
|
||||
let warningDialog = new MessageBox("Delete User Error", "An error occurred while deleting the user.");
|
||||
warningDialog.open();
|
||||
}
|
||||
});
|
||||
}));
|
||||
warningDialog.addButton(new ModalButton("Cancel", 0, warningDialog, async (callingObject) => {
|
||||
callingObject.msgDialog.close();
|
||||
}));
|
||||
warningDialog.open();
|
||||
});
|
||||
deleteButton.classList.add('romlink');
|
||||
|
||||
let deleteButtonImage = document.createElement('img');
|
||||
deleteButtonImage.src = '/images/delete.svg';
|
||||
deleteButtonImage.classList.add('banner_button_image');
|
||||
deleteButtonImage.alt = 'Delete';
|
||||
deleteButtonImage.title = 'Delete';
|
||||
deleteButton.appendChild(deleteButtonImage);
|
||||
|
||||
controls.appendChild(deleteButton);
|
||||
}
|
||||
|
||||
newTable.appendChild(
|
||||
createTableRow(
|
||||
false,
|
||||
[
|
||||
userAvatar,
|
||||
result[i].emailAddress,
|
||||
roleDiv,
|
||||
ageRestrictionPolicyDescription,
|
||||
controls
|
||||
],
|
||||
'romrow',
|
||||
'romcell'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
targetDiv.appendChild(newTable);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
class UserNew {
|
||||
constructor() {
|
||||
|
||||
}
|
||||
|
||||
async open() {
|
||||
// Create the modal
|
||||
this.dialog = await new Modal("usernew");
|
||||
await this.dialog.BuildModal();
|
||||
|
||||
// setup the dialog
|
||||
this.dialog.modalElement.querySelector('#modal-header-text').innerHTML = "New User";
|
||||
this.dialog.modalElement.style = 'width: 550px; height: 380px; min-width: unset; min-height: unset; max-width: unset; max-height: unset;';
|
||||
|
||||
// setup email check
|
||||
this.email = this.dialog.modalElement.querySelector('#email-address');
|
||||
this.email_error = this.dialog.modalElement.querySelector('#email-error');
|
||||
this.EmailCheck = new EmailCheck(this.email, this.email_error);
|
||||
|
||||
// setup password check
|
||||
this.password_new = this.dialog.modalElement.querySelector('#new-password');
|
||||
this.password_confirm = this.dialog.modalElement.querySelector('#confirm-new-password');
|
||||
this.password_error = this.dialog.modalElement.querySelector('#password-error');
|
||||
this.PasswordCheck = new PasswordCheck(this.password_new, this.password_confirm, this.password_error);
|
||||
|
||||
// add the ok button
|
||||
let okButton = new ModalButton("OK", 1, this, async function (callingObject) {
|
||||
if (!await EmailCheck.CheckEmail(callingObject.EmailCheck, callingObject.email)) {
|
||||
// display an error
|
||||
let warningDialog = new MessageBox("New User Error", "Invalid email address. Please correct the errors before continuing.");
|
||||
warningDialog.open();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PasswordCheck.CheckPasswords(callingObject.PasswordCheck, callingObject.password_new, callingObject.password_confirm)) {
|
||||
// display an error
|
||||
let warningDialog = new MessageBox("New User Error", "The password doesn't meet the requirements. Please correct the errors before continuing.");
|
||||
warningDialog.open();
|
||||
return;
|
||||
}
|
||||
|
||||
// create the new user
|
||||
var model = {
|
||||
"userName": callingObject.email.value,
|
||||
"email": callingObject.email.value,
|
||||
"password": callingObject.password_new.value,
|
||||
"confirmPassword": callingObject.password_confirm.value
|
||||
}
|
||||
|
||||
fetch("/api/v1.1/Account/Users", {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(model)
|
||||
}).then(async response => {
|
||||
if (response.ok) {
|
||||
let result = await response.json();
|
||||
GetUsers();
|
||||
callingObject.dialog.close();
|
||||
} else {
|
||||
let result = await response.json();
|
||||
let warningDialog = new MessageBox("New User Error", "An error occurred while creating the user. Check that the email address is valid and the password meets the requirements.");
|
||||
warningDialog.open();
|
||||
}
|
||||
});
|
||||
});
|
||||
this.dialog.addButton(okButton);
|
||||
|
||||
// add the cancel button
|
||||
let cancelButton = new ModalButton("Cancel", 0, this, async function (callingObject) {
|
||||
callingObject.dialog.close();
|
||||
});
|
||||
this.dialog.addButton(cancelButton);
|
||||
|
||||
// show the dialog
|
||||
await this.dialog.open();
|
||||
}
|
||||
}
|
||||
|
||||
class UserEdit {
|
||||
constructor(UserId, OkCallback, CancelCallback) {
|
||||
this.userId = UserId;
|
||||
this.okCallback = OkCallback;
|
||||
this.cancelCallback = CancelCallback;
|
||||
}
|
||||
|
||||
async open() {
|
||||
// Create the modal
|
||||
this.dialog = await new Modal("useredit");
|
||||
await this.dialog.BuildModal();
|
||||
|
||||
await fetch("/api/v1.1/Account/Users/" + this.userId, {
|
||||
method: 'GET'
|
||||
}).then(async response => {
|
||||
if (response.ok) {
|
||||
let result = await response.json();
|
||||
this.user = result;
|
||||
} else {
|
||||
let result = await response.json();
|
||||
let warningDialog = new MessageBox("Edit User Error", "An error occurred while retrieving the user.");
|
||||
warningDialog.open();
|
||||
}
|
||||
});
|
||||
|
||||
// setup the dialog
|
||||
if (this.user.profileId == "00000000-0000-0000-0000-000000000000") {
|
||||
this.dialog.modalElement.querySelector('#modal-header-text').innerHTML = this.user.emailAddress;
|
||||
} else {
|
||||
await fetch("/api/v1.1/UserProfile/" + this.user.profileId, {
|
||||
method: 'GET'
|
||||
}).then(async response => {
|
||||
if (response.ok) {
|
||||
let result = await response.json();
|
||||
this.profile = result;
|
||||
this.dialog.modalElement.querySelector('#modal-header-text').innerHTML = this.profile.displayName + ' (' + this.user.emailAddress + ')';
|
||||
} else {
|
||||
this.dialog.modalElement.querySelector('#modal-header-text').innerHTML = this.user.emailAddress;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// setup general page
|
||||
this.dialog.modalElement.querySelector('#user-id').innerHTML = this.user.id;
|
||||
let userProfileCard = new ProfileCard(this.user.profileId, true);
|
||||
if (this.user.lockoutEnabled === true) {
|
||||
this.dialog.modalElement.querySelector('#user-lockedout').innerHTML = 'Locked';
|
||||
this.dialog.modalElement.querySelector('#user-lockedout').style.backgroundColor = 'red';
|
||||
this.dialog.modalElement.querySelector('#user-lockedout-end').innerHTML = 'until ' + new Date(this.user.lockoutEnd).toLocaleString();
|
||||
} else {
|
||||
this.dialog.modalElement.querySelector('#user-lockedout').innerHTML = 'Unlocked';
|
||||
this.dialog.modalElement.querySelector('#user-lockedout').style.backgroundColor = '';
|
||||
this.dialog.modalElement.querySelector('#user-lockedout-end').innerHTML = '';
|
||||
}
|
||||
this.dialog.modalElement.querySelector('#user-profile-card').appendChild(userProfileCard);
|
||||
|
||||
// set user role
|
||||
this.role_Player = this.dialog.modalElement.querySelector('#settings_user_role_player');
|
||||
this.role_Player.addEventListener('change', () => {
|
||||
this.UpdateRolePermissionsDisplay();
|
||||
});
|
||||
this.role_Gamer = this.dialog.modalElement.querySelector('#settings_user_role_gamer');
|
||||
this.role_Gamer.addEventListener('change', () => {
|
||||
this.UpdateRolePermissionsDisplay();
|
||||
});
|
||||
this.role_Admin = this.dialog.modalElement.querySelector('#settings_user_role_admin');
|
||||
this.role_Admin.addEventListener('change', () => {
|
||||
this.UpdateRolePermissionsDisplay();
|
||||
});
|
||||
this.dialog.modalElement.querySelector('#settings_user_role_' + this.user.highestRole.toLowerCase()).checked = true;
|
||||
this.UpdateRolePermissionsDisplay();
|
||||
|
||||
this.rolePermTable = this.dialog.modalElement.querySelector('#role-permissions-table');
|
||||
this.rolePermCover = this.dialog.modalElement.querySelector('#role-permissions-expand');
|
||||
this.rolePermLink = this.dialog.modalElement.querySelector('#role-permissions-expand-link');
|
||||
this.rolePermLink.addEventListener('click', () => {
|
||||
if (Array.from(this.rolePermTable.classList).includes('collapsed')) {
|
||||
this.rolePermTable.classList.remove('collapsed');
|
||||
this.rolePermTable.classList.add('expanded');
|
||||
this.rolePermCover.classList.remove('collapsed');
|
||||
this.rolePermCover.classList.add('expanded');
|
||||
this.rolePermLink.innerHTML = 'Hide details...';
|
||||
} else {
|
||||
this.rolePermTable.classList.remove('expanded');
|
||||
this.rolePermTable.classList.add('collapsed');
|
||||
this.rolePermCover.classList.remove('expanded');
|
||||
this.rolePermCover.classList.add('collapsed');
|
||||
this.rolePermLink.innerHTML = 'Show details...';
|
||||
}
|
||||
});
|
||||
|
||||
// setup age restriction tab
|
||||
let ageRestrictionPolicyBox = this.dialog.modalElement.querySelector('#settings_user_agerestrictions');
|
||||
let ageRestrictionPolicyTable = document.createElement('table');
|
||||
for (let ageGroup in AgeRatingGroups) {
|
||||
let tRow = document.createElement('tr');
|
||||
let tCell = document.createElement('td');
|
||||
|
||||
let ageGroupRadio = document.createElement('input');
|
||||
ageGroupRadio.type = 'radio';
|
||||
ageGroupRadio.name = 'ageGroup';
|
||||
ageGroupRadio.value = ageGroup;
|
||||
ageGroupRadio.id = 'ageGroup_' + ageGroup;
|
||||
ageGroupRadio.addEventListener('change', () => {
|
||||
this.UpdateAssignedAgeGroupDisplay();
|
||||
});
|
||||
tCell.appendChild(ageGroupRadio);
|
||||
|
||||
let ageGroupLabel = document.createElement('label');
|
||||
ageGroupLabel.htmlFor = 'ageGroup_' + ageGroup;
|
||||
ageGroupLabel.innerHTML = ageGroup;
|
||||
tCell.appendChild(ageGroupLabel);
|
||||
|
||||
tRow.appendChild(tCell);
|
||||
ageRestrictionPolicyTable.appendChild(tRow);
|
||||
}
|
||||
// add allow unclassified titles checkbox
|
||||
let tRow = document.createElement('tr');
|
||||
let tCell = document.createElement('td');
|
||||
let includeUnratedCheckbox = document.createElement('input');
|
||||
includeUnratedCheckbox.type = 'checkbox';
|
||||
includeUnratedCheckbox.id = 'includeUnrated';
|
||||
includeUnratedCheckbox.addEventListener('change', () => {
|
||||
this.UpdateAssignedAgeGroupDisplay();
|
||||
});
|
||||
tCell.appendChild(includeUnratedCheckbox);
|
||||
let includeUnratedLabel = document.createElement('label');
|
||||
includeUnratedLabel.htmlFor = 'includeUnrated';
|
||||
includeUnratedLabel.innerHTML = 'Include unrated titles';
|
||||
tCell.appendChild(includeUnratedLabel);
|
||||
tRow.appendChild(tCell);
|
||||
ageRestrictionPolicyTable.appendChild(tRow);
|
||||
ageRestrictionPolicyBox.appendChild(ageRestrictionPolicyTable);
|
||||
|
||||
this.dialog.modalElement.querySelector('#ageGroup_' + this.user.securityProfile.ageRestrictionPolicy.maximumAgeRestriction).checked = true;
|
||||
if (this.user.securityProfile.ageRestrictionPolicy.includeUnrated === true) {
|
||||
this.dialog.modalElement.querySelector('#includeUnrated').checked = true;
|
||||
}
|
||||
this.UpdateAssignedAgeGroupDisplay();
|
||||
|
||||
this.agePermTable = this.dialog.modalElement.querySelector('#settings_user_agerestrictions_preview');
|
||||
this.agePermCover = this.dialog.modalElement.querySelector('#settings_user_agerestrictions_expand');
|
||||
this.agePermLink = this.dialog.modalElement.querySelector('#settings_user_agerestrictions_expand-link');
|
||||
this.agePermLink.addEventListener('click', () => {
|
||||
if (Array.from(this.agePermTable.classList).includes('collapsed')) {
|
||||
this.agePermTable.classList.remove('collapsed');
|
||||
this.agePermTable.classList.add('expanded');
|
||||
this.agePermCover.classList.remove('collapsed');
|
||||
this.agePermCover.classList.add('expanded');
|
||||
this.agePermLink.innerHTML = 'Hide details...';
|
||||
} else {
|
||||
this.agePermTable.classList.remove('expanded');
|
||||
this.agePermTable.classList.add('collapsed');
|
||||
this.agePermCover.classList.remove('expanded');
|
||||
this.agePermCover.classList.add('collapsed');
|
||||
this.agePermLink.innerHTML = 'Show details...';
|
||||
}
|
||||
});
|
||||
|
||||
// set up the password change form
|
||||
this.password_new = this.dialog.modalElement.querySelector('#new-password');
|
||||
this.password_confirm = this.dialog.modalElement.querySelector('#confirm-new-password');
|
||||
this.password_error = this.dialog.modalElement.querySelector('#password-error');
|
||||
this.PasswordCheck = new PasswordCheck(this.password_new, this.password_confirm, this.password_error);
|
||||
|
||||
// create the ok button
|
||||
let okButton = new ModalButton("OK", 1, this, async function (callingObject) {
|
||||
// check if a new password has been entered
|
||||
if (callingObject.password_new.value.length > 0 && callingObject.password_confirm.value.length > 0) {
|
||||
// check if the new password meets the rules
|
||||
if (!PasswordCheck.CheckPasswords(callingObject.PasswordCheck, callingObject.password_new, callingObject.password_confirm)) {
|
||||
// display an error
|
||||
let warningDialog = new MessageBox("Password Reset Error", "The new password does not meet the requirements.");
|
||||
warningDialog.open();
|
||||
return;
|
||||
}
|
||||
|
||||
// requirements met, reset the password
|
||||
let model = {
|
||||
newPassword: callingObject.password_new.value,
|
||||
confirmPassword: callingObject.password_confirm.value
|
||||
};
|
||||
let changeSuccessfull = false;
|
||||
await fetch("/api/v1.1/Account/Users/" + callingObject.userId + "/Password", {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(model)
|
||||
}).then(async response => {
|
||||
if (!response.ok) {
|
||||
// handle the error
|
||||
console.error("Error updating password:");
|
||||
console.error(response);
|
||||
let warningDialog = new MessageBox("Password Reset Error", "The password reset failed. Check the current password and try again.");
|
||||
warningDialog.open();
|
||||
changeSuccessfull = false;
|
||||
return;
|
||||
} else {
|
||||
// clear the password fields
|
||||
callingObject.password_new.value = "";
|
||||
callingObject.password_confirm.value = "";
|
||||
callingObject.password_error.innerHTML = "";
|
||||
changeSuccessfull = true;
|
||||
}
|
||||
});
|
||||
if (changeSuccessfull == false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// set the role
|
||||
let selectedRole = callingObject.dialog.modalElement.querySelector('input[name="settings_user_role"]:checked').value.toLowerCase();
|
||||
await fetch("/api/v1.1/Account/Users/" + callingObject.userId + "/Roles?RoleName=" + selectedRole, {
|
||||
method: 'POST'
|
||||
}).then(async response => {
|
||||
if (!response.ok) {
|
||||
// handle the error
|
||||
console.error("Error updating role:");
|
||||
console.error(response);
|
||||
let warningDialog = new MessageBox("Role Update Error", "The role update failed. Check the role and try again.");
|
||||
warningDialog.open();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
// set the security profile
|
||||
let securityProfile = {
|
||||
"ageRestrictionPolicy": {
|
||||
"maximumAgeRestriction": callingObject.dialog.modalElement.querySelector('input[name="ageGroup"]:checked').value,
|
||||
"includeUnrated": callingObject.dialog.modalElement.querySelector('#includeUnrated').checked
|
||||
}
|
||||
};
|
||||
await fetch("/api/v1.1/Account/Users/" + callingObject.userId + "/SecurityProfile", {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(securityProfile)
|
||||
}).then(async response => {
|
||||
if (!response.ok) {
|
||||
// handle the error
|
||||
console.error("Error updating security profile:");
|
||||
console.error(response);
|
||||
let warningDialog = new MessageBox("Security Profile Update Error", "The security profile update failed. Check the settings and try again.");
|
||||
warningDialog.open();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if (callingObject.okCallback) {
|
||||
callingObject.okCallback();
|
||||
}
|
||||
callingObject.dialog.close();
|
||||
});
|
||||
this.dialog.addButton(okButton);
|
||||
|
||||
// create the cancel button
|
||||
let cancelButton = new ModalButton("Cancel", 0, this, function (callingObject) {
|
||||
if (callingObject.cancelCallback) {
|
||||
callingObject.cancelCallback();
|
||||
}
|
||||
|
||||
callingObject.dialog.close();
|
||||
});
|
||||
this.dialog.addButton(cancelButton);
|
||||
|
||||
// show the dialog
|
||||
this.dialog.open();
|
||||
}
|
||||
|
||||
UpdateRolePermissionsDisplay() {
|
||||
// get selected role
|
||||
let selectedRole = this.dialog.modalElement.querySelector('input[name="settings_user_role"]:checked').value.toLowerCase();
|
||||
|
||||
// get the player role icons
|
||||
let playerPermssions = this.dialog.modalElement.querySelectorAll('td[name="role-player"]');
|
||||
playerPermssions.forEach(element => {
|
||||
if (selectedRole == 'player') {
|
||||
element.style.display = '';
|
||||
} else {
|
||||
element.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// get the gamer role icons
|
||||
let gamerPermssions = this.dialog.modalElement.querySelectorAll('td[name="role-gamer"]');
|
||||
gamerPermssions.forEach(element => {
|
||||
if (selectedRole == 'gamer') {
|
||||
element.style.display = '';
|
||||
} else {
|
||||
element.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// get the admin role icons
|
||||
let adminPermssions = this.dialog.modalElement.querySelectorAll('td[name="role-admin"]');
|
||||
adminPermssions.forEach(element => {
|
||||
if (selectedRole == 'admin') {
|
||||
element.style.display = '';
|
||||
} else {
|
||||
element.style.display = 'none';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
UpdateAssignedAgeGroupDisplay() {
|
||||
// get the selected age group
|
||||
let selectedAgeGroup = this.dialog.modalElement.querySelector('input[name="ageGroup"]:checked').value;
|
||||
|
||||
let ageGroupList = [];
|
||||
switch (selectedAgeGroup) {
|
||||
case "Adult":
|
||||
ageGroupList = ["Child", "Teen", "Mature", "Adult"];
|
||||
break;
|
||||
case "Mature":
|
||||
ageGroupList = ["Child", "Teen", "Mature"];
|
||||
break;
|
||||
case "Teen":
|
||||
ageGroupList = ["Child", "Teen"];
|
||||
break;
|
||||
case "Child":
|
||||
ageGroupList = ["Child"];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// get target div
|
||||
let assignedAgeGroup = this.dialog.modalElement.querySelector('#settings_user_agerestrictions_preview');
|
||||
assignedAgeGroup.innerHTML = '';
|
||||
|
||||
// generate restrictions table
|
||||
let ageRestrictionPolicyTable = document.createElement('table');
|
||||
ageRestrictionPolicyTable.classList.add('romtable');
|
||||
ageRestrictionPolicyTable.setAttribute('cellspacing', '0');
|
||||
for (const [key, value] of Object.entries(ClassificationBoards)) {
|
||||
let thRow = document.createElement('tr');
|
||||
let thCell = document.createElement('th');
|
||||
thCell.innerHTML = value;
|
||||
thRow.appendChild(thCell);
|
||||
ageRestrictionPolicyTable.appendChild(thRow);
|
||||
|
||||
// add age rating icons
|
||||
let trRow = document.createElement('tr');
|
||||
let tdCell = document.createElement('td');
|
||||
|
||||
for (let i = 0; i < ageGroupList.length; i++) {
|
||||
let ageRatingBadgeIndexes = AgeRatingGroups[ageGroupList[i]][key];
|
||||
|
||||
for (let j = 0; j < ageRatingBadgeIndexes.length; j++) {
|
||||
let ageRatingBatch = document.createElement('img');
|
||||
ageRatingBatch.src = '/images/Ratings/' + key + '/' + AgeRatingStrings[ageRatingBadgeIndexes[j]] + '.svg';
|
||||
ageRatingBatch.classList.add('rating_image_mini');
|
||||
ageRatingBatch.setAttribute('title', ClassificationRatings[AgeRatingStrings[ageRatingBadgeIndexes[j]]]);
|
||||
tdCell.appendChild(ageRatingBatch);
|
||||
}
|
||||
|
||||
ageRestrictionPolicyTable.appendChild(trRow);
|
||||
}
|
||||
|
||||
trRow.appendChild(tdCell);
|
||||
ageRestrictionPolicyTable.appendChild(trRow);
|
||||
}
|
||||
assignedAgeGroup.appendChild(ageRestrictionPolicyTable);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user