Channel Management, Sorting, Grouping
This commit is contained in:
+1282
-1282
File diff suppressed because it is too large
Load Diff
@@ -100,3 +100,23 @@
|
||||
.drag-handle:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.channel-group-heading {
|
||||
margin: 1.25rem 0 0.5rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-left: 4px solid var(--accent);
|
||||
background: var(--panel-2);
|
||||
color: var(--text);
|
||||
font-weight: 700;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
#groupFilter {
|
||||
min-width: 180px;
|
||||
height: 38px;
|
||||
padding: 0 0.75rem;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
background: var(--panel);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
@@ -26,11 +26,15 @@ class SenderSyncService
|
||||
}
|
||||
|
||||
$existing[$id] = [
|
||||
'id' => $id,
|
||||
'name' => $channel['name'] ?? $id,
|
||||
'enabled' => false,
|
||||
'favorite' => false,
|
||||
'number' => 999999,
|
||||
'uuid' => bin2hex(random_bytes(16)),
|
||||
'name' => $channel['name'] ?? $id,
|
||||
'icon' => $channel['icon'] ?? '',
|
||||
'country' => '',
|
||||
'language' => $channel['language'] ?? '',
|
||||
'enabled' => false,
|
||||
'favorite' => false,
|
||||
'number' => 999999,
|
||||
'group' => $this->detectGroup($id),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -45,4 +49,16 @@ class SenderSyncService
|
||||
|
||||
return $existing;
|
||||
}
|
||||
|
||||
private function detectGroup(string $id): string
|
||||
{
|
||||
$id = strtolower($id);
|
||||
|
||||
return match (true) {
|
||||
str_ends_with($id, '.at') => 'Österreich',
|
||||
str_ends_with($id, '.de') => 'Deutschland',
|
||||
str_ends_with($id, '.ch') => 'Schweiz',
|
||||
default => 'Sonstige',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+43
-12
@@ -14,6 +14,27 @@
|
||||
<div class="channel-toolbar">
|
||||
<input type="search" id="channelSearch" placeholder="Sender suchen...">
|
||||
|
||||
<?php
|
||||
$groups = [];
|
||||
|
||||
foreach ($channelConfig as $channel) {
|
||||
$group = $channel['group'] ?? 'Sonstige';
|
||||
$groups[$group] = true;
|
||||
}
|
||||
|
||||
ksort($groups, SORT_NATURAL | SORT_FLAG_CASE);
|
||||
?>
|
||||
|
||||
<select id="groupFilter">
|
||||
<option value="">Alle Gruppen</option>
|
||||
|
||||
<?php foreach (array_keys($groups) as $group): ?>
|
||||
<option value="<?= htmlspecialchars($group) ?>">
|
||||
<?= htmlspecialchars($group) ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
|
||||
<div class="channel-filter-buttons">
|
||||
<button type="button" data-filter="all" class="active">Alle</button>
|
||||
<button type="button" data-filter="enabled">Aktiv</button>
|
||||
@@ -48,6 +69,7 @@
|
||||
data-name="<?= htmlspecialchars(strtolower($name . ' ' . $id)) ?>"
|
||||
data-enabled="<?= $enabled ? '1' : '0' ?>"
|
||||
data-favorite="<?= $favorite ? '1' : '0' ?>"
|
||||
data-group="<?= htmlspecialchars($channel['group'] ?? 'Sonstige') ?>"
|
||||
data-original-enabled="<?= $enabled ? '1' : '0' ?>"
|
||||
data-original-favorite="<?= $favorite ? '1' : '0' ?>"
|
||||
data-original-number="<?= $number ?>"
|
||||
@@ -95,6 +117,7 @@
|
||||
const filterButtons = Array.from(document.querySelectorAll('[data-filter]'));
|
||||
const enableVisible = document.getElementById('enableVisible');
|
||||
const disableVisible = document.getElementById('disableVisible');
|
||||
const groupFilter = document.getElementById('groupFilter');
|
||||
|
||||
let currentFilter = 'all';
|
||||
let draggedCard = null;
|
||||
@@ -146,23 +169,30 @@
|
||||
|
||||
function applyFilter() {
|
||||
const q = search.value.trim().toLowerCase();
|
||||
const selectedGroup = groupFilter.value;
|
||||
let count = 0;
|
||||
|
||||
cards.forEach(card => {
|
||||
refreshCardState(card);
|
||||
refreshCardState(card);
|
||||
|
||||
const matchesSearch = !q || card.dataset.name.includes(q);
|
||||
const matchesFilter =
|
||||
currentFilter === 'all' ||
|
||||
(currentFilter === 'enabled' && card.dataset.enabled === '1') ||
|
||||
(currentFilter === 'disabled' && card.dataset.enabled === '0') ||
|
||||
(currentFilter === 'favorite' && card.dataset.favorite === '1') ||
|
||||
(currentFilter === 'changed' && card.dataset.changed === '1');
|
||||
const matchesSearch = !q || card.dataset.name.includes(q);
|
||||
|
||||
const visible = matchesSearch && matchesFilter;
|
||||
card.style.display = visible ? '' : 'none';
|
||||
const matchesFilter =
|
||||
currentFilter === 'all' ||
|
||||
(currentFilter === 'enabled' && card.dataset.enabled === '1') ||
|
||||
(currentFilter === 'disabled' && card.dataset.enabled === '0') ||
|
||||
(currentFilter === 'favorite' && card.dataset.favorite === '1') ||
|
||||
(currentFilter === 'changed' && card.dataset.changed === '1');
|
||||
|
||||
if (visible) count++;
|
||||
const matchesGroup =
|
||||
!selectedGroup ||
|
||||
card.dataset.group === selectedGroup;
|
||||
|
||||
const visible = matchesSearch && matchesFilter && matchesGroup;
|
||||
|
||||
card.style.display = visible ? '' : 'none';
|
||||
|
||||
if (visible) count++;
|
||||
});
|
||||
|
||||
visibleCount.textContent = count;
|
||||
@@ -193,7 +223,6 @@
|
||||
let number = 10;
|
||||
|
||||
Array.from(list.querySelectorAll('.channel-settings-card'))
|
||||
.filter(card => card.style.display !== 'none')
|
||||
.forEach(card => {
|
||||
card.querySelector('.number-input').value = number;
|
||||
number += 10;
|
||||
@@ -264,6 +293,8 @@
|
||||
|
||||
search.addEventListener('input', applyFilter);
|
||||
|
||||
groupFilter.addEventListener('change', applyFilter);
|
||||
|
||||
cards.forEach(card => {
|
||||
card.querySelectorAll('input').forEach(input => {
|
||||
input.addEventListener('input', applyFilter);
|
||||
|
||||
Reference in New Issue
Block a user