openpanel/templates/admini/emails/accounts.html

396 lines
12 KiB
HTML

{% extends 'base.html' %}
{% block content %}
<style>
td {vertical-align: middle;}
@media (min-width: 768px) {
table.table {
table-layout: fixed;
}
table.table td {
word-wrap: break-word;
}
}
@media (max-width: 767px) {
span.advanced-text {display:none;}
}
.hidden {
display: none;
}
.advanced-settings {
align-items: center;
text-align: right;
color: black;
}
.advanced-settings i {
margin-right: 5px;
transform: rotate(-90deg);
transition: transform 0.3s ease-in-out;
}
[data-bs-theme=light] .domain_link {
color: black;
}
.domain_link {
border-bottom: 1px dashed #999;
text-decoration: none;
}
.advanced-settings.active i {
transform: rotate(0);
}
thead {
border: 1px solid rgb(90 86 86 / 11%);
}
th {
text-transform: uppercase;
font-weight: 400;
}
</style>
<div class="row">
<div class="collapse mb-2" id="addEmailForm" style="display: none;">
<div class="card card-body">
<div class="container">
<a href="#" class="nije-link" id="cancelLinkemails" style="display: none;"><i class="bi bi-x-lg" style="right: 15px;top: 15px;position: absolute;color: black;padding: 6px 10px;border-radius: 50px;"></i></a>
<div class="row">
<div class="col-md-6 offset-md-3">
<h2 class="mb-3"><i class="bi bi-envelope-plus"></i> {{ _("Create new email account") }}</h2>
<p>{{ _("Use this form to create new email addresses for any of the domains on your account.") }}</p>
<form action="/emails" method="post">
<div class="form-group">
<label for="domain" class="form-label" data-toggle="tooltip" data-placement="top" title="{{ _('Choose the domain that you want to use. Your email address will end with this domain (username@domain.com).') }}">{{ _("Domain:") }}</label>
<div class="input-group">
</select>
<select class="form-select" name="domain" id="domain">
{% for domain in domains %}
<option class="punycode" value="{{ domain.domain_url }}">{{ domain.domain_url }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<label for="at_address" data-toggle="tooltip" data-placement="top" title="{{ _('Enter the username that you want to use. Your email address will start with this username (username@domain.com).') }}">{{ _("Username:") }}</label>
<input type="text" class="form-control" name="email_username" required>
<div class="input-group-append" style="width: 100%;">
<input type="text" class="form-control" width="40%" name="at_address" id="at_address" disabled>
</div>
</div>
<script>
$(document).ready(function() {
// Check if the URL contains the parameter "install"
const urlParams = new URLSearchParams(window.location.search);
const installParam = urlParams.get('create');
if (installParam || window.location.hash === '#create') {
// Show the Bootstrap collapsible element
$("#addEmailForm").collapse('show');
}
// Add event listener to the dropdown
$("#domain").change(function() {
// Get the selected domain URL
var selectedDomain = $("#domain option:selected").text();
// Update the admin email input value
var adminEmailInput = $("#at_address");
var currentAdminEmail = adminEmailInput.val();
adminEmailInput.val('@' + selectedDomain);
});
// Add event listener to the "Install WordPress" button to toggle form and jumbotron
$("#addEmailForm").on('shown.bs.collapse', function () {
$("#jumbotronSection").hide();
$("#cancelLinkemails").show();
});
// Add event listener to the "Cancel" link to toggle form and jumbotron
$("#cancelLinkemails").click(function() {
$("#addEmailForm").collapse('hide');
$("#jumbotronSection").show();
$("#cancelLinkemails").hide();
});
});
var selectedDomain = $("#domain option:selected").text();
// Update the admin email input value
var adminEmailInput = $("#at_address");
var currentAdminEmail = adminEmailInput.val();
adminEmailInput.val('@' + selectedDomain);
</script>
<div class="form-group">
<label for="email_password" class="form-label">{{ _("Password:") }}</label>
<div class="input-group">
<input type="password" class="form-control" name="email_password" id="email_password" required>
<div class="input-group-append">
<button class="btn btn-outline-success" type="button" id="generatePassword">
{{ _("Generate") }}
</button>
<button class="btn btn-outline-secondary" type="button" id="togglePassword">
<i class="bi bi-eye"></i>
</button>
</div>
</div>
</div>
<script>
function generateRandomStrongPassword(length) {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
let result = "";
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * charset.length);
result += charset.charAt(randomIndex);
}
return result;
}
function generateInitiallyUsernameAndPassword() {
const generatedPassword = generateRandomStrongPassword(16);
document.getElementById("email_password").value = generatedPassword;
};
generateInitiallyUsernameAndPassword();
document.getElementById("generatePassword").addEventListener("click", function() {
const generatedPassword = generateRandomStrongPassword(16);
document.getElementById("email_password").value = generatedPassword;
const passwordField = document.getElementById("email_password");
if (passwordField.type === "password") {
passwordField.type = "text";
}
});
document.getElementById("togglePassword").addEventListener("click", function() {
const passwordField = document.getElementById("email_password");
if (passwordField.type === "password") {
passwordField.type = "text";
} else {
passwordField.type = "password";
}
});
</script>
<br>
<button type="submit" class="btn btn-primary">{{ _("Create") }}</button>
</form>
</div>
</div>
</div>
</div>
</div>
<table class="table table-hover">
<thead>
<tr>
<th width="">{{ _('Account @ Domain') }}</th>
<th width="" data-toggle="tooltip" data-placement="bottom" title="{{ _('Current disk usage for the email account.') }}">{{ _('Storage') }}<span class="desktop-only">{{ _(' Used') }}</span></th>
<th width="">{{ _('Options') }}</th>
</tr>
</thead>
<tbody>
{% for email_entry in current_emails_list %}
{% set parts = email_entry.split(' ') %}
{% set status = parts[0] %}
{% set address = parts[1] %}
{% set quota = ' '.join(parts[2:]) %}
{% set quota_parts = quota.split('[') %}
{% if quota_parts|length > 1 %}
{% set percentage_str = quota_parts[1].split(']')[0] %}
{% else %}
{% set percentage_str = '0' %}
{% endif %}
<tr class="domain_row">
<td><span class="punycode">{{ address }}</span>
<td>{{ quota }}
<br>
<div class="progress" style="height: 10px;">
<div id="disk-progress-bar" class="progress-bar w-4 bg-success" role="progressbar" aria-valuemin="0" aria-valuemax="100" style="width: {{ percentage_str }};"></div>
</div>
</td>
<td>
<div class="flex">
<a href="/webmail/{{ address }}" class="btn btn-primary btn-sm webmail-link" data-email="{{ address }}" role="button"><i class="bi bi-box-arrow-up-right"></i> Webmail</a>
<a href="/emails/{{ address }}" class="btn btn-outline-primary btn-sm" role="button"><i class="bi bi-wrench-adjustable"></i> Manage</a>
<a href="/emails/connect/{{ address }}" class="btn btn-outline-primary d-none btn-sm" role="button"><i class="bi bi-phone"></i> Connect Devices</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<script>
document.addEventListener("DOMContentLoaded", function() {
// Attach event listener to all webmail links
document.querySelectorAll('.webmail-link').forEach(function(link) {
link.addEventListener('click', function(e) {
e.preventDefault(); // Prevent the default link behavior
const email = this.dataset.email; // Get the email from the data attribute
const url = `/webmail/${email}`; // Construct the URL
let btnClass, toastMessage;
btnClass = 'primary';
toastMessage = "{{ _('Webmail for ') }}" + email + "{{ _(' opened in new window.') }}";
const toast = toaster({
body: toastMessage,
className: `border-0 text-white bg-${btnClass}`,
});
window.open(url, '_blank');
});
});
});
</script>
</section>
<footer class="main-footer btn-toolbar" role="toolbar">
<div class="btn-group" role="group" aria-label="{{ _('Status') }}">
<input type="text" class="form-control" placeholder="{{ _('Search addresses') }}" id="searchDomainInput">
</div>
<div class="ms-auto" role="group" aria-label="{{ _('Actions') }}">
<button type="button" class="btn btn-primary d-flex align-items-center gap-2" id="showAddEmailFormBtn"><i class="bi bi-plus-lg"></i> <span class="desktop-only">{{ _('Create') }}</span></button>
</div>
</footer>
<script>
function initializeDomainManagement() {
// Get references to search input and display settings div
const searchDomainInput = document.getElementById("searchDomainInput");
// Get all domain rows to be used for filtering
const domainRows = document.querySelectorAll(".domain_row");
// Handle search input changes
searchDomainInput.addEventListener("input", function() {
const searchTerm = searchDomainInput.value.trim().toLowerCase();
// Loop through domain rows and hide/show based on search term
domainRows.forEach(function(row) {
const domainName = row.querySelector("td:nth-child(1)").textContent.toLowerCase();
const domainUrl = row.querySelector("td:nth-child(2)").textContent.toLowerCase();
// Show row if search term matches domain name or domain URL, otherwise hide it
if (domainName.includes(searchTerm) || domainUrl.includes(searchTerm)) {
row.style.display = "table-row";
} else {
row.style.display = "none";
}
});
});
}
initializeDomainManagement ();
// Toggle display of "Add New Domain" form
const showAddEmailFormBtn = document.getElementById("showAddEmailFormBtn");
showAddEmailFormBtn.addEventListener("click", function() {
addEmailForm.style.display = addEmailForm.style.display === "none" ? "block" : "none";
});
function toggleEmailDomainForm() {
const currentFragment = window.location.hash;
const addNewFragment = "#create";
if (currentFragment === addNewFragment) {
addEmailForm.style.display = "block";
} else {
addEmailForm.style.display = "none";
}
}
// Listen for changes in the URL's fragment identifier
window.addEventListener("hashchange", toggleEmailDomainForm);
// Check the initial fragment identifier when the page loads
window.addEventListener("load", toggleEmailDomainForm);
</script>
{% endblock %}