Files
domnitor/app/Views/groups/index.twig

337 lines
19 KiB
Twig
Raw Normal View History

{% extends 'layout/base.twig' %}
{% set title = 'Notification Groups' %}
{% set pageTitle = 'Notification Groups' %}
{% set pageDescription = 'Manage notification channels and assignments' %}
{% set pageIcon = 'fas fa-bell' %}
{% block content %}
{# Quick Actions #}
<div class="mb-4 flex gap-2 justify-end">
{# Export Dropdown #}
<div class="relative" id="groupExportDropdownWrapper">
<button onclick="document.getElementById('groupExportMenu').classList.toggle('hidden')" class="inline-flex items-center px-4 py-2 bg-emerald-600 text-white text-sm rounded-lg hover:bg-emerald-700 transition-colors font-medium">
<i class="fas fa-download mr-2"></i>
Export
<i class="fas fa-chevron-down ml-2 text-xs"></i>
</button>
<div id="groupExportMenu" class="hidden absolute right-0 mt-1 w-44 bg-white dark:bg-slate-800 rounded-lg shadow-lg border border-gray-200 dark:border-slate-700 z-30 overflow-hidden">
<a href="/groups/export?format=csv" class="flex items-center px-4 py-2.5 text-sm text-gray-700 dark:text-slate-300 hover:bg-gray-50 dark:hover:bg-slate-700 transition-colors">
<i class="fas fa-file-csv text-green-600 mr-2.5"></i>
Export as CSV
</a>
<a href="/groups/export?format=json" class="flex items-center px-4 py-2.5 text-sm text-gray-700 dark:text-slate-300 hover:bg-gray-50 dark:hover:bg-slate-700 transition-colors border-t border-gray-100 dark:border-slate-700">
<i class="fas fa-file-code text-blue-600 mr-2.5"></i>
Export as JSON
</a>
</div>
</div>
{# Import Button #}
<button onclick="document.getElementById('groupImportModal').classList.remove('hidden')" class="inline-flex items-center px-4 py-2 bg-primary text-white text-sm rounded-lg hover:bg-primary-dark transition-colors font-medium">
<i class="fas fa-upload mr-2"></i>
Import
</button>
<a href="/groups/create" class="inline-flex items-center px-4 py-2 bg-primary text-white text-sm rounded-lg hover:bg-primary-dark transition-colors font-medium">
2025-10-08 14:23:07 +03:00
<i class="fas fa-plus mr-2"></i>
Create New Group
</a>
</div>
{# Info Card #}
<div class="bg-blue-50 dark:bg-blue-500/10 border border-blue-200 dark:border-blue-500/30 rounded-lg p-4 mb-4">
2025-10-08 14:23:07 +03:00
<div class="flex items-start">
<div class="flex-shrink-0">
<i class="fas fa-info-circle text-blue-500 text-lg"></i>
</div>
<div class="ml-3">
<h3 class="text-sm font-semibold text-gray-900 dark:text-white mb-1">About Notification Groups</h3>
<p class="text-xs text-gray-600 dark:text-slate-400 leading-relaxed">
Notification groups allow you to organize your notification channels. You can create multiple channels
(Email, Telegram, Discord, Slack, Mattermost, Pushover, Webhook) within each group, then assign domains to the group. When a domain
2025-10-08 14:23:07 +03:00
is about to expire, all active channels in its group will receive notifications.
</p>
</div>
</div>
</div>
{# Groups List #}
<div class="bg-white dark:bg-slate-800 rounded-lg border border-gray-200 dark:border-slate-700 overflow-hidden">
{# Bulk Actions Bar (shown when groups are selected) #}
<div id="bulk-actions" class="hidden px-6 py-3 bg-blue-50 dark:bg-blue-500/10 border-b border-blue-200 dark:border-blue-500/30 flex items-center justify-between">
<div class="flex items-center gap-4">
<span id="selected-count" class="text-sm font-medium text-gray-700 dark:text-slate-300"></span>
<div class="flex items-center gap-3 flex-wrap">
<div class="flex items-center gap-2">
{% if auth.isAdmin %}
<button type="button" onclick="bulkTransfer()" class="inline-flex items-center px-4 py-1.5 bg-primary text-white rounded-lg hover:bg-primary-dark transition-colors text-sm font-medium">
<i class="fas fa-exchange-alt mr-1"></i> Transfer Selected
</button>
{% endif %}
<button type="button" onclick="bulkDelete()" class="inline-flex items-center px-4 py-1.5 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors text-sm font-medium">
<i class="fas fa-trash mr-1"></i> Delete Selected
</button>
</div>
</div>
</div>
<button type="button" onclick="clearSelection()" class="inline-flex items-center text-sm font-medium text-gray-600 dark:text-slate-400 hover:text-gray-900 dark:hover:text-white hover:bg-blue-100 dark:hover:bg-blue-500/20 px-3 py-1.5 rounded-lg transition-colors">
<i class="fas fa-times mr-1.5"></i> Clear Selection
</button>
</div>
{% if groups is not empty %}
{# Table View (Desktop) #}
2025-10-08 14:23:07 +03:00
<div class="hidden md:block overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 dark:divide-slate-700">
<thead class="bg-gray-50 dark:bg-slate-900">
2025-10-08 14:23:07 +03:00
<tr>
<th class="px-6 py-3 text-left">
<input type="checkbox" id="select-all" onchange="toggleSelectAll(this)" class="rounded border-gray-300 dark:border-slate-600 text-primary focus:ring-primary">
</th>
<th class="px-6 py-4 text-left text-xs font-semibold text-gray-600 dark:text-slate-400 uppercase tracking-wider">Group Name</th>
<th class="px-6 py-4 text-left text-xs font-semibold text-gray-600 dark:text-slate-400 uppercase tracking-wider">Description</th>
<th class="px-6 py-4 text-left text-xs font-semibold text-gray-600 dark:text-slate-400 uppercase tracking-wider">Channels</th>
<th class="px-6 py-4 text-left text-xs font-semibold text-gray-600 dark:text-slate-400 uppercase tracking-wider">Domains</th>
<th class="px-6 py-4 text-right text-xs font-semibold text-gray-600 dark:text-slate-400 uppercase tracking-wider">Actions</th>
2025-10-08 14:23:07 +03:00
</tr>
</thead>
<tbody class="bg-white dark:bg-slate-800 divide-y divide-gray-200 dark:divide-slate-700">
{% for group in groups %}
<tr class="hover:bg-gray-50 dark:hover:bg-slate-700 transition-colors duration-150">
<td class="px-6 py-4">
<input type="checkbox" class="group-checkbox rounded border-gray-300 dark:border-slate-600 text-primary focus:ring-primary" value="{{ group.id }}" onchange="updateBulkActions()">
</td>
2025-10-08 14:23:07 +03:00
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="flex-shrink-0 h-10 w-10 bg-primary bg-opacity-10 rounded-lg flex items-center justify-center">
<i class="fas fa-bell text-primary"></i>
</div>
<div class="ml-4">
<div class="text-sm font-semibold text-gray-900 dark:text-white">{{ group.name }}</div>
2025-10-08 14:23:07 +03:00
</div>
</div>
</td>
<td class="px-6 py-4">
<div class="text-sm text-gray-700 dark:text-slate-300 max-w-xs truncate">
{{ group.description|default('No description') }}
2025-10-08 14:23:07 +03:00
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-blue-100 dark:bg-blue-500/20 text-blue-800 dark:text-blue-400">
2025-10-08 14:23:07 +03:00
<i class="fas fa-plug mr-1"></i>
{{ group.channel_count }} channel{{ group.channel_count != 1 ? 's' : '' }}
2025-10-08 14:23:07 +03:00
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-green-100 dark:bg-green-500/20 text-green-800 dark:text-green-400">
2025-10-08 14:23:07 +03:00
<i class="fas fa-globe mr-1"></i>
{{ group.domain_count }} domain{{ group.domain_count != 1 ? 's' : '' }}
2025-10-08 14:23:07 +03:00
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<div class="flex items-center justify-end space-x-2">
<a href="/groups/{{ group.id }}/edit" class="text-blue-600 hover:text-blue-800" title="Manage">
2025-10-08 14:23:07 +03:00
<i class="fas fa-cog"></i>
</a>
{% if auth.isAdmin %}
<button onclick="transferGroup({{ group.id }}, '{{ group.name|e('js') }}')"
class="text-green-600 hover:text-green-800"
title="Transfer Group">
<i class="fas fa-exchange-alt"></i>
</button>
{% endif %}
Enhance DNS discovery, validation & transfers Add comprehensive DNS management and input validation, plus safer transfer and logging behavior. - Add CronHelper utilities for cron scripts and unify logging/formatting. - Improve InputValidator: sanitizeDomainInput and validateRootDomain (handles multi-level TLDs) and use throughout domain import/create flows to reject subdomains. - DomainController: refactor DNS refresh to support quick/deep discovery (background deep scans), add endpoints to discover, add/delete/bulk-delete DNS records, import BIND zone files, enrich IP metadata via enrichIpDetails, and strengthen bulk import/reporting messages. - DnsRecord model: add source column handling (discovered/manual/imported), avoid auto-deleting manual/imported records, and add helpers for deleting, bulk deleting, manual adding and importing zone records. - Tag, NotificationGroup and Domain transfer logic: unlink groups when ownership changes, remove tags that belong to other users, add audit logging via Logger and improved bulk transfer reporting. TagController/View: show transferable users for admins and skip global tags on transfer. - Notification channels (Discord, Mattermost, etc.) and EmailHelper: allow explicit subjects and improve payload fields based on notification type. - Add new migration 029_add_dns_record_source.sql and wire it into the installer; update migrations detection. - Add new views/partials for confirm/import/transfer modals, update various domain/group/tag templates, and update cron scripts and routes for discovery. These changes preserve manual/imported DNS records, improve root-domain validation, enable background deep discovery, and add better logging/audit trails for transfers and imports.
2026-03-10 22:54:28 +02:00
<form method="POST" action="/groups/{{ group.id }}/delete" class="inline" onsubmit="return confirmSubmit(event, 'Are you sure? Domains will be unassigned from this group.')">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<button type="submit" class="text-red-600 hover:text-red-800" title="Delete"
aria-label="Delete group {{ group.name }}">
<i class="fas fa-trash"></i>
</button>
</form>
2025-10-08 14:23:07 +03:00
</div>
</td>
</tr>
{% endfor %}
2025-10-08 14:23:07 +03:00
</tbody>
</table>
</div>
{# Card View (Mobile) #}
<div class="md:hidden divide-y divide-gray-200 dark:divide-slate-700">
{% for group in groups %}
<div class="p-6 hover:bg-gray-50 dark:hover:bg-slate-700 transition-colors duration-150">
2025-10-08 14:23:07 +03:00
<div class="flex items-start justify-between mb-3">
<div class="flex items-center">
<div class="flex-shrink-0 h-10 w-10 bg-primary bg-opacity-10 rounded-lg flex items-center justify-center">
<i class="fas fa-bell text-primary"></i>
</div>
<div class="ml-3">
<h3 class="font-semibold text-gray-900 dark:text-white">{{ group.name }}</h3>
<p class="text-sm text-gray-500 dark:text-slate-400">{{ group.description|default('No description') }}</p>
2025-10-08 14:23:07 +03:00
</div>
</div>
</div>
2025-10-08 14:23:07 +03:00
<div class="flex space-x-3 mb-3">
<span class="px-2 py-1 rounded-full text-xs font-medium bg-blue-100 dark:bg-blue-500/20 text-blue-800 dark:text-blue-400">
2025-10-08 14:23:07 +03:00
<i class="fas fa-plug mr-1"></i>
{{ group.channel_count }} channels
2025-10-08 14:23:07 +03:00
</span>
<span class="px-2 py-1 rounded-full text-xs font-medium bg-green-100 dark:bg-green-500/20 text-green-800 dark:text-green-400">
2025-10-08 14:23:07 +03:00
<i class="fas fa-globe mr-1"></i>
{{ group.domain_count }} domains
2025-10-08 14:23:07 +03:00
</span>
</div>
2025-10-08 14:23:07 +03:00
<div class="flex space-x-2">
<a href="/groups/{{ group.id }}/edit" class="flex-1 px-3 py-1.5 bg-blue-50 dark:bg-blue-500/10 text-blue-600 dark:text-blue-400 rounded text-center text-sm hover:bg-blue-100 dark:hover:bg-blue-500/20 transition-colors">
2025-10-08 14:23:07 +03:00
<i class="fas fa-cog mr-1"></i> Manage
</a>
Enhance DNS discovery, validation & transfers Add comprehensive DNS management and input validation, plus safer transfer and logging behavior. - Add CronHelper utilities for cron scripts and unify logging/formatting. - Improve InputValidator: sanitizeDomainInput and validateRootDomain (handles multi-level TLDs) and use throughout domain import/create flows to reject subdomains. - DomainController: refactor DNS refresh to support quick/deep discovery (background deep scans), add endpoints to discover, add/delete/bulk-delete DNS records, import BIND zone files, enrich IP metadata via enrichIpDetails, and strengthen bulk import/reporting messages. - DnsRecord model: add source column handling (discovered/manual/imported), avoid auto-deleting manual/imported records, and add helpers for deleting, bulk deleting, manual adding and importing zone records. - Tag, NotificationGroup and Domain transfer logic: unlink groups when ownership changes, remove tags that belong to other users, add audit logging via Logger and improved bulk transfer reporting. TagController/View: show transferable users for admins and skip global tags on transfer. - Notification channels (Discord, Mattermost, etc.) and EmailHelper: allow explicit subjects and improve payload fields based on notification type. - Add new migration 029_add_dns_record_source.sql and wire it into the installer; update migrations detection. - Add new views/partials for confirm/import/transfer modals, update various domain/group/tag templates, and update cron scripts and routes for discovery. These changes preserve manual/imported DNS records, improve root-domain validation, enable background deep discovery, and add better logging/audit trails for transfers and imports.
2026-03-10 22:54:28 +02:00
<form method="POST" action="/groups/{{ group.id }}/delete" class="flex-1" onsubmit="return confirmSubmit(event, 'Are you sure? Domains will be unassigned from this group.')">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<button type="submit" class="w-full px-3 py-1.5 bg-red-50 dark:bg-red-500/10 text-red-600 dark:text-red-400 rounded text-center text-sm hover:bg-red-100 dark:hover:bg-red-500/20 transition-colors">
<i class="fas fa-trash mr-1"></i> Delete
</button>
</form>
2025-10-08 14:23:07 +03:00
</div>
</div>
{% endfor %}
2025-10-08 14:23:07 +03:00
</div>
{% else %}
2025-10-08 14:23:07 +03:00
<div class="text-center py-12 px-6">
<div class="mb-4">
<i class="fas fa-bell-slash text-gray-300 dark:text-slate-600 text-6xl"></i>
2025-10-08 14:23:07 +03:00
</div>
<h3 class="text-lg font-semibold text-gray-700 dark:text-slate-300 mb-1">No Notification Groups</h3>
<p class="text-sm text-gray-500 dark:text-slate-400 mb-4">Create your first notification group to start receiving alerts</p>
2025-10-08 14:23:07 +03:00
<a href="/groups/create" class="inline-flex items-center px-5 py-2.5 bg-primary text-white text-sm rounded-lg hover:bg-primary-dark transition-colors font-medium">
<i class="fas fa-plus mr-2"></i>
Create Your First Group
</a>
</div>
{% endif %}
2025-10-08 14:23:07 +03:00
</div>
<script>
function toggleSelectAll(checkbox) {
const checkboxes = document.querySelectorAll('.group-checkbox');
checkboxes.forEach(cb => {
cb.checked = checkbox.checked;
});
updateBulkActions();
}
function updateBulkActions() {
const checkboxes = document.querySelectorAll('.group-checkbox:checked');
const bulkActions = document.getElementById('bulk-actions');
const selectedCount = document.getElementById('selected-count');
const selectAllCheckbox = document.getElementById('select-all');
if (checkboxes.length > 0) {
bulkActions.classList.remove('hidden');
selectedCount.textContent = checkboxes.length + ' group(s) selected';
} else {
bulkActions.classList.add('hidden');
}
const allCheckboxes = document.querySelectorAll('.group-checkbox');
if (selectAllCheckbox) {
selectAllCheckbox.checked = allCheckboxes.length > 0 && checkboxes.length === allCheckboxes.length;
selectAllCheckbox.indeterminate = checkboxes.length > 0 && checkboxes.length < allCheckboxes.length;
}
}
function clearSelection() {
const checkboxes = document.querySelectorAll('.group-checkbox');
checkboxes.forEach(cb => {
cb.checked = false;
});
document.getElementById('select-all').checked = false;
updateBulkActions();
}
function getSelectedGroupIds() {
const checkboxes = document.querySelectorAll('.group-checkbox:checked');
return Array.from(checkboxes).map(cb => cb.value);
}
Enhance DNS discovery, validation & transfers Add comprehensive DNS management and input validation, plus safer transfer and logging behavior. - Add CronHelper utilities for cron scripts and unify logging/formatting. - Improve InputValidator: sanitizeDomainInput and validateRootDomain (handles multi-level TLDs) and use throughout domain import/create flows to reject subdomains. - DomainController: refactor DNS refresh to support quick/deep discovery (background deep scans), add endpoints to discover, add/delete/bulk-delete DNS records, import BIND zone files, enrich IP metadata via enrichIpDetails, and strengthen bulk import/reporting messages. - DnsRecord model: add source column handling (discovered/manual/imported), avoid auto-deleting manual/imported records, and add helpers for deleting, bulk deleting, manual adding and importing zone records. - Tag, NotificationGroup and Domain transfer logic: unlink groups when ownership changes, remove tags that belong to other users, add audit logging via Logger and improved bulk transfer reporting. TagController/View: show transferable users for admins and skip global tags on transfer. - Notification channels (Discord, Mattermost, etc.) and EmailHelper: allow explicit subjects and improve payload fields based on notification type. - Add new migration 029_add_dns_record_source.sql and wire it into the installer; update migrations detection. - Add new views/partials for confirm/import/transfer modals, update various domain/group/tag templates, and update cron scripts and routes for discovery. These changes preserve manual/imported DNS records, improve root-domain validation, enable background deep discovery, and add better logging/audit trails for transfers and imports.
2026-03-10 22:54:28 +02:00
async function bulkDelete() {
const groupIds = getSelectedGroupIds();
if (groupIds.length === 0) {
alert('Please select at least one group to delete');
return;
}
Enhance DNS discovery, validation & transfers Add comprehensive DNS management and input validation, plus safer transfer and logging behavior. - Add CronHelper utilities for cron scripts and unify logging/formatting. - Improve InputValidator: sanitizeDomainInput and validateRootDomain (handles multi-level TLDs) and use throughout domain import/create flows to reject subdomains. - DomainController: refactor DNS refresh to support quick/deep discovery (background deep scans), add endpoints to discover, add/delete/bulk-delete DNS records, import BIND zone files, enrich IP metadata via enrichIpDetails, and strengthen bulk import/reporting messages. - DnsRecord model: add source column handling (discovered/manual/imported), avoid auto-deleting manual/imported records, and add helpers for deleting, bulk deleting, manual adding and importing zone records. - Tag, NotificationGroup and Domain transfer logic: unlink groups when ownership changes, remove tags that belong to other users, add audit logging via Logger and improved bulk transfer reporting. TagController/View: show transferable users for admins and skip global tags on transfer. - Notification channels (Discord, Mattermost, etc.) and EmailHelper: allow explicit subjects and improve payload fields based on notification type. - Add new migration 029_add_dns_record_source.sql and wire it into the installer; update migrations detection. - Add new views/partials for confirm/import/transfer modals, update various domain/group/tag templates, and update cron scripts and routes for discovery. These changes preserve manual/imported DNS records, improve root-domain validation, enable background deep discovery, and add better logging/audit trails for transfers and imports.
2026-03-10 22:54:28 +02:00
var ok = await confirmAction({ message: 'Are you sure you want to delete ' + groupIds.length + ' group(s)? Domains will be unassigned from these groups.' });
if (!ok) return;
const form = document.createElement('form');
form.method = 'POST';
form.action = '/groups/bulk-delete';
const csrfInput = document.createElement('input');
csrfInput.type = 'hidden';
csrfInput.name = 'csrf_token';
csrfInput.value = '{{ csrf_token() }}';
form.appendChild(csrfInput);
const idsInput = document.createElement('input');
idsInput.type = 'hidden';
idsInput.name = 'group_ids';
idsInput.value = JSON.stringify(groupIds);
form.appendChild(idsInput);
document.body.appendChild(form);
form.submit();
}
function transferGroup(groupId, groupName) {
Enhance DNS discovery, validation & transfers Add comprehensive DNS management and input validation, plus safer transfer and logging behavior. - Add CronHelper utilities for cron scripts and unify logging/formatting. - Improve InputValidator: sanitizeDomainInput and validateRootDomain (handles multi-level TLDs) and use throughout domain import/create flows to reject subdomains. - DomainController: refactor DNS refresh to support quick/deep discovery (background deep scans), add endpoints to discover, add/delete/bulk-delete DNS records, import BIND zone files, enrich IP metadata via enrichIpDetails, and strengthen bulk import/reporting messages. - DnsRecord model: add source column handling (discovered/manual/imported), avoid auto-deleting manual/imported records, and add helpers for deleting, bulk deleting, manual adding and importing zone records. - Tag, NotificationGroup and Domain transfer logic: unlink groups when ownership changes, remove tags that belong to other users, add audit logging via Logger and improved bulk transfer reporting. TagController/View: show transferable users for admins and skip global tags on transfer. - Notification channels (Discord, Mattermost, etc.) and EmailHelper: allow explicit subjects and improve payload fields based on notification type. - Add new migration 029_add_dns_record_source.sql and wire it into the installer; update migrations detection. - Add new views/partials for confirm/import/transfer modals, update various domain/group/tag templates, and update cron scripts and routes for discovery. These changes preserve manual/imported DNS records, improve root-domain validation, enable background deep discovery, and add better logging/audit trails for transfers and imports.
2026-03-10 22:54:28 +02:00
const esc = (s) => String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
openTransferModal({
title: 'Transfer Group',
description: 'Transfer group <strong>' + esc(groupName) + '</strong> to another user.',
action: '/groups/transfer',
fields: { group_id: groupId },
users: {{ users|default([])|json_encode|raw }},
csrfToken: '{{ csrf_token() }}'
});
}
function bulkTransfer() {
const groupIds = getSelectedGroupIds();
if (groupIds.length === 0) {
alert('Please select groups to transfer');
return;
}
Enhance DNS discovery, validation & transfers Add comprehensive DNS management and input validation, plus safer transfer and logging behavior. - Add CronHelper utilities for cron scripts and unify logging/formatting. - Improve InputValidator: sanitizeDomainInput and validateRootDomain (handles multi-level TLDs) and use throughout domain import/create flows to reject subdomains. - DomainController: refactor DNS refresh to support quick/deep discovery (background deep scans), add endpoints to discover, add/delete/bulk-delete DNS records, import BIND zone files, enrich IP metadata via enrichIpDetails, and strengthen bulk import/reporting messages. - DnsRecord model: add source column handling (discovered/manual/imported), avoid auto-deleting manual/imported records, and add helpers for deleting, bulk deleting, manual adding and importing zone records. - Tag, NotificationGroup and Domain transfer logic: unlink groups when ownership changes, remove tags that belong to other users, add audit logging via Logger and improved bulk transfer reporting. TagController/View: show transferable users for admins and skip global tags on transfer. - Notification channels (Discord, Mattermost, etc.) and EmailHelper: allow explicit subjects and improve payload fields based on notification type. - Add new migration 029_add_dns_record_source.sql and wire it into the installer; update migrations detection. - Add new views/partials for confirm/import/transfer modals, update various domain/group/tag templates, and update cron scripts and routes for discovery. These changes preserve manual/imported DNS records, improve root-domain validation, enable background deep discovery, and add better logging/audit trails for transfers and imports.
2026-03-10 22:54:28 +02:00
openTransferModal({
title: 'Transfer Groups',
description: 'Transfer ' + groupIds.length + ' selected group(s) to another user.',
action: '/groups/bulk-transfer',
fields: { 'group_ids[]': groupIds },
submitText: 'Transfer All',
users: {{ users|default([])|json_encode|raw }},
csrfToken: '{{ csrf_token() }}'
});
}
document.addEventListener('click', function(e) {
const wrapper = document.getElementById('groupExportDropdownWrapper');
if (wrapper && !wrapper.contains(e.target)) {
document.getElementById('groupExportMenu').classList.add('hidden');
}
});
document.getElementById('groupImportModal')?.addEventListener('click', function(e) {
if (e.target === this) {
this.classList.add('hidden');
}
});
</script>
Enhance DNS discovery, validation & transfers Add comprehensive DNS management and input validation, plus safer transfer and logging behavior. - Add CronHelper utilities for cron scripts and unify logging/formatting. - Improve InputValidator: sanitizeDomainInput and validateRootDomain (handles multi-level TLDs) and use throughout domain import/create flows to reject subdomains. - DomainController: refactor DNS refresh to support quick/deep discovery (background deep scans), add endpoints to discover, add/delete/bulk-delete DNS records, import BIND zone files, enrich IP metadata via enrichIpDetails, and strengthen bulk import/reporting messages. - DnsRecord model: add source column handling (discovered/manual/imported), avoid auto-deleting manual/imported records, and add helpers for deleting, bulk deleting, manual adding and importing zone records. - Tag, NotificationGroup and Domain transfer logic: unlink groups when ownership changes, remove tags that belong to other users, add audit logging via Logger and improved bulk transfer reporting. TagController/View: show transferable users for admins and skip global tags on transfer. - Notification channels (Discord, Mattermost, etc.) and EmailHelper: allow explicit subjects and improve payload fields based on notification type. - Add new migration 029_add_dns_record_source.sql and wire it into the installer; update migrations detection. - Add new views/partials for confirm/import/transfer modals, update various domain/group/tag templates, and update cron scripts and routes for discovery. These changes preserve manual/imported DNS records, improve root-domain validation, enable background deep discovery, and add better logging/audit trails for transfers and imports.
2026-03-10 22:54:28 +02:00
{% include 'partials/import-modal.twig' with {
prefix: 'group',
title: 'Import Notification Groups',
action: '/groups/import',
format_html: '<p class="text-xs text-gray-600 dark:text-slate-400">CSV: <code class="bg-white dark:bg-slate-700 px-1 rounded">group_name, group_description, channel_type, channel_config, is_active</code></p><p class="text-xs text-gray-600 dark:text-slate-400 mt-0.5">JSON: array of group objects with nested channels array</p><p class="text-xs text-gray-500 dark:text-slate-400 mt-1.5"><i class="fas fa-exclamation-triangle text-amber-500 mr-1"></i>Channels with masked secrets will be imported as <strong>disabled</strong>. Update the credentials and enable them manually.</p>'
} %}
{% include 'partials/transfer-modal.twig' %}
{% endblock %}