Merge branch 'main' into decrypt
This commit is contained in:
@@ -13,9 +13,12 @@
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-9 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon organize">settings_account_box</span>
|
||||
<span class="tool-header-text" th:text="#{account.accountSettings}">User Settings</span>
|
||||
</div>
|
||||
|
||||
<!-- User Settings Title -->
|
||||
<h2 class="text-center" th:text="#{account.accountSettings}">User Settings</h2>
|
||||
<th:block th:if="${messageType}">
|
||||
<div class="alert alert-danger">
|
||||
<span th:text="#{${messageType}}">Default message if not found</span>
|
||||
@@ -247,9 +250,9 @@
|
||||
<table id="settingsTable" class="table table-bordered table-sm table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th th:text="#{account.property}">Property</th>
|
||||
<th th:text="#{account.accountSettings}">Account Setting</th>
|
||||
<th th:text="#{account.webBrowserSettings}">Web Browser Setting</th>
|
||||
<th scope="col" th:text="#{account.property}">Property</th>
|
||||
<th scope="col" th:text="#{account.accountSettings}">Account Setting</th>
|
||||
<th scope="col" th:text="#{account.webBrowserSettings}">Web Browser Setting</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
@@ -12,10 +12,13 @@
|
||||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8 bg-card">
|
||||
<div class="col-md-9 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon organize">manage_accounts</span>
|
||||
<span class="tool-header-text" th:text="#{adminUserSettings.header}">Admin User Control Settings</span>
|
||||
</div>
|
||||
|
||||
<!-- User Settings Title -->
|
||||
<h2 class="text-center" th:text="#{adminUserSettings.header}">Admin User Control Settings</h2>
|
||||
<div style="background: var(--md-sys-color-outline-variant);padding: .8rem; margin: 10px 0; border-radius: 2rem; text-align: center;">
|
||||
<a href="#" data-bs-toggle="modal" data-bs-target="#addUserModal" class="btn btn-outline-info" th:title="#{adminUserSettings.addUser}">
|
||||
<span class="material-symbols-rounded">person_add</span>
|
||||
@@ -29,35 +32,39 @@
|
||||
<div th:if="${deleteMessage}" class="alert alert-danger">
|
||||
<span th:text="#{${deleteMessage}}">Message</span>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th th:text="#{username}">Username</th>
|
||||
<th th:text="#{adminUserSettings.roles}">Roles</th>
|
||||
<th th:text="#{adminUserSettings.actions}">Actions</th>
|
||||
<th th:text="#{adminUserSettings.authenticated}">Authenticated</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="user : ${users}">
|
||||
<td style="align-content: center;" th:text="${user.username}"></td>
|
||||
<td style="align-content: center;" th:text="#{${user.roleName}}"></td>
|
||||
<td style="align-content: center;">
|
||||
<form th:if="${user.username != currentUsername}" th:action="@{'/api/v1/user/admin/deleteUser/' + ${user.username}}" method="post" onsubmit="return confirmDelete()">
|
||||
<button type="submit" th:title="#{adminUserSettings.deleteUser}" class="btn btn-info"><span class="material-symbols-rounded">person_remove</span></button>
|
||||
</form>
|
||||
<script th:inline="javascript">
|
||||
const confirm_text = /*[[#{adminUserSettings.confirmDeleteUser}]]*/ 'Should the user be deleted?';
|
||||
function confirmDelete() {
|
||||
return confirm(confirm_text);
|
||||
}
|
||||
</script>
|
||||
<a th:if="${user.username == currentUsername}" th:href="@{'/account'}" class="btn btn-outline-info"><span class="material-symbols-rounded">edit</span></a>
|
||||
</td>
|
||||
<td style="align-content: center;" th:text="${user.authenticationType}"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="bg-card mt-3 mb-3">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">UID</th>
|
||||
<th scope="col" th:text="#{username}">Username</th>
|
||||
<th scope="col" th:text="#{adminUserSettings.roles}">Roles</th>
|
||||
<th scope="col" th:text="#{adminUserSettings.actions}">Actions</th>
|
||||
<th scope="col" th:text="#{adminUserSettings.authenticated}">Authenticated</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="user : ${users}">
|
||||
<th scope="row" style="align-content: center;" th:text="${user.id}"></th>
|
||||
<td style="align-content: center;" th:text="${user.username}"></td>
|
||||
<td style="align-content: center;" th:text="#{${user.roleName}}"></td>
|
||||
<td style="align-content: center;">
|
||||
<form th:if="${user.username != currentUsername}" th:action="@{'/api/v1/user/admin/deleteUser/' + ${user.username}}" method="post" onsubmit="return confirmDelete()">
|
||||
<button type="submit" th:title="#{adminUserSettings.deleteUser}" class="btn btn-info"><span class="material-symbols-rounded">person_remove</span></button>
|
||||
</form>
|
||||
<a th:if="${user.username == currentUsername}" th:href="@{'/account'}" class="btn btn-outline-info"><span class="material-symbols-rounded">edit</span></a>
|
||||
</td>
|
||||
<td style="align-content: center;" th:text="${user.authenticationType}"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<script th:inline="javascript">
|
||||
const confirm_text = /*[[#{adminUserSettings.confirmDeleteUser}]]*/ 'Should the user be deleted?';
|
||||
function confirmDelete() {
|
||||
return confirm(confirm_text);
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
71
src/main/resources/templates/database.html
Normal file
71
src/main/resources/templates/database.html
Normal file
@@ -0,0 +1,71 @@
|
||||
<!DOCTYPE html>
|
||||
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}" xmlns:th="https://www.thymeleaf.org">
|
||||
<head>
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{database.title}, header=#{database.header})}"></th:block>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
||||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-9 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon organize">database</span>
|
||||
<span class="tool-header-text" text="#{database.title}">Database Im-/Export</span>
|
||||
</div>
|
||||
<p th:if="${error}" th:text="#{'database.' + ${error}}" class="alert alert-danger text-center"></p>
|
||||
<p th:if="${infoMessage}" th:text="#{'database.' + ${infoMessage}}" class="alert alert-success text-center"></p>
|
||||
<div class="bg-card mt-3 mb-3">
|
||||
<table class="table table-striped table-hover mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" th:text="#{database.fileName}">File Name</th>
|
||||
<th scope="col" th:text="#{database.creationDate}">Creation Date</th>
|
||||
<th scope="col" th:text="#{database.fileSize}">File Size</th>
|
||||
<th scope="col"></th>
|
||||
<th scope="col"></th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="backup : ${systemUpdate}">
|
||||
<td th:text="${backup.fileName}"></td>
|
||||
<td th:text="${backup.formattedCreationDate}"></td>
|
||||
<td th:text="${backup.formattedFileSize}"></td>
|
||||
<td th:title="#{database.deleteBackupFile}"><a th:href="@{'/api/v1/database/delete/' + ${backup.fileName}}" style="color: red;"><span class="material-symbols-rounded">delete</span></a></td>
|
||||
<td th:title="#{database.importBackupFile}"><a th:href="@{'/api/v1/database/import-database-file/' + ${backup.fileName}}" style="color: var(--md-nav-section-color-organize);"><span class="material-symbols-rounded">backup</span></a></td>
|
||||
<td th:title="#{database.downloadBackupFile}"><a th:href="@{'/api/v1/database/download/' + ${backup.fileName}}"><span class="material-symbols-rounded">download</span></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<hr>
|
||||
<form th:action="@{'/api/v1/database/import-database'}" method="post" enctype="multipart/form-data" class="bg-card mt-3 mb-3">
|
||||
<div style="background: var(--md-sys-color-error-container);padding: .8rem;border-radius: 2rem;" class="mb-3">
|
||||
<p th:text="#{database.info_1}"></p>
|
||||
<p th:text="#{database.info_2}"></p>
|
||||
</div>
|
||||
<div class="custom-file-chooser">
|
||||
<div class="mb-3">
|
||||
<input type="file" class="form-control" th:name="fileInput" id="fileInput-input" accept=".sql" required>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{database.submit}">Import Backup</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script th:inline="javascript">
|
||||
const pdfPasswordPrompt = /*[[#{error.pdfPassword}]]*/ '';
|
||||
const multiple = /*[[${multiple}]]*/ false;
|
||||
const remoteCall = /*[[${remoteCall}]]*/ true;
|
||||
</script>
|
||||
<script th:src="@{'/js/fileInput.js'}"></script>
|
||||
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -13,7 +13,7 @@
|
||||
<link rel="apple-touch-icon" sizes="180x180" th:href="@{'/apple-touch-icon.png'}">
|
||||
<link rel="icon" type="image/png" sizes="32x32" th:href="@{'/favicon-32x32.png'}">
|
||||
<link rel="icon" type="image/png" sizes="16x16" th:href="@{'/favicon-16x16.png'}">
|
||||
<link rel="manifest" th:href="@{'/site.webmanifest'}">
|
||||
<link rel="manifest" th:href="@{'/site.webmanifest'}" crossorigin="use-credentials">
|
||||
<link rel="mask-icon" th:href="@{'/safari-pinned-tab.svg'}" color="#ca2b2a">
|
||||
<link rel="shortcut icon" th:href="@{'/favicon.ico'}">
|
||||
<meta name="apple-mobile-web-app-title" content="Stirling PDF">
|
||||
|
||||
@@ -274,7 +274,7 @@
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#" th:href="@{'/split-pdfs'}"
|
||||
th:classappend="${currentPage}=='split-pdfs' ? 'active' : ''" th:title="#{home.split-pdfs.desc}">
|
||||
th:classappend="${currentPage}=='split-pdfs' ? 'active' : ''" th:title="#{home.split.desc}">
|
||||
<span class="material-symbols-rounded">
|
||||
cut
|
||||
</span>
|
||||
|
||||
@@ -11,14 +11,17 @@
|
||||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6 bg-card">
|
||||
<h2 th:text="#{licenses.header}">3rd Party licenses</h2>
|
||||
<div class="col-md-8 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon organize">license</span>
|
||||
<span class="tool-header-text" th:text="#{licenses.header}">3rd Party licenses</span>
|
||||
</div>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th th:text="#{licenses.module}">Module</th>
|
||||
<th th:text="#{licenses.version}">Version</th>
|
||||
<th th:text="#{licenses.license}">License</th>
|
||||
<th scope="col" th:text="#{licenses.module}">Module</th>
|
||||
<th scope="col" th:text="#{licenses.version}">Version</th>
|
||||
<th scope="col" th:text="#{licenses.license}">License</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
@@ -6,10 +6,36 @@
|
||||
.result-column {
|
||||
border: 1px solid #ccc;
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
overflow-y: auto;
|
||||
height: calc(100vh - 400px);
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.flex-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.color-selector {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
width: 50%;
|
||||
max-height: 100px;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
#color-box1, #color-box2 {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
.spacer1 {
|
||||
padding-right: calc(var(--bs-gutter-x) * .5);
|
||||
}
|
||||
.spacer2 {
|
||||
padding-left: calc(var(--bs-gutter-x) * .5);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@@ -27,7 +53,22 @@
|
||||
</div>
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf', remoteCall='false')}"></div>
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput2', multiple=false, accept='application/pdf', remoteCall='false')}"></div>
|
||||
|
||||
<div class="row">
|
||||
<div class="flex-container">
|
||||
<div class="color-selector spacer1">
|
||||
<label th:text="#{compare.highlightColor.1}"></label>
|
||||
<label for="color-box1"></label><input type="color" id="color-box1" value="#ff0000">
|
||||
</div>
|
||||
<div class="color-selector spacer2">
|
||||
<label th:text="#{compare.highlightColor.2}"></label>
|
||||
<label for="color-box2"></label><input type="color" id="color-box2" value="#008000">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary" onclick="comparePDFs()" th:text="#{compare.submit}"></button>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3 th:text="#{compare.document.1}"></h3>
|
||||
@@ -55,6 +96,8 @@
|
||||
async function comparePDFs() {
|
||||
const file1 = document.getElementById("fileInput-input").files[0];
|
||||
const file2 = document.getElementById("fileInput2-input").files[0];
|
||||
var color1 = document.getElementById('color-box1').value;
|
||||
var color2 = document.getElementById('color-box2').value;
|
||||
|
||||
if (!file1 || !file2) {
|
||||
console.error("Please select two PDF files to compare");
|
||||
@@ -115,13 +158,15 @@
|
||||
i--;
|
||||
j--;
|
||||
} else if (j > 0 && (i === 0 || matrix[i][j - 1] >= matrix[i - 1][j])) {
|
||||
differences.unshift(['green', words2[j - 1]]);
|
||||
differences.unshift([color2, words2[j - 1]]);
|
||||
j--;
|
||||
} else if (i > 0 && (j === 0 || matrix[i][j - 1] < matrix[i - 1][j])) {
|
||||
differences.unshift(['red', words1[i - 1]]);
|
||||
differences.unshift([color1, words1[i - 1]]);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
console.log(differences);
|
||||
|
||||
|
||||
return differences;
|
||||
};
|
||||
@@ -138,14 +183,14 @@
|
||||
const span1 = document.createElement("span");
|
||||
const span2 = document.createElement("span");
|
||||
|
||||
// If it's an addition, show it in green in the second document and transparent in the first
|
||||
if (color === "green") {
|
||||
// If it's an addition, show it in color2 in the second document and transparent in the first
|
||||
if (color === color2) {
|
||||
span1.style.color = "transparent";
|
||||
span1.style.userSelect = "none";
|
||||
span2.style.color = color;
|
||||
}
|
||||
// If it's a deletion, show it in red in the first document and transparent in the second
|
||||
else if (color === "red") {
|
||||
// If it's a deletion, show it in color1 in the first document and transparent in the second
|
||||
else if (color === color1) {
|
||||
span1.style.color = color;
|
||||
span2.style.color = "transparent";
|
||||
span2.style.userSelect = "none";
|
||||
|
||||
Reference in New Issue
Block a user