feat(sources): Quellenuebersicht nach Quellentyp filterbar

Der Typ-Filter im Quellen-Modal kennt jetzt auch podcast_feed, damit
alle Quellentypen (RSS, Web, Telegram, X, Podcast) filterbar sind.
Zusaetzlich zeigt jede Quelle ein korrektes Typ-Badge -- vorher zeigten
Telegram, X und Podcast faelschlich "Web".

- podcast_feed im sources-filter-type-Dropdown
- _sourceTypeLabel-Helfer, korrekte Typ-Badges im Gruppen-Header und in
  den Feed-Zeilen, x_account im Info-Tooltip-typeMap

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dieser Commit ist enthalten in:
Claude Code
2026-05-22 13:31:04 +00:00
Ursprung 9598063728
Commit a0f4572a01
2 geänderte Dateien mit 9 neuen und 3 gelöschten Zeilen

Datei anzeigen

@@ -492,6 +492,7 @@
<option value="web_source">Web-Quelle</option> <option value="web_source">Web-Quelle</option>
<option value="telegram_channel">Telegram</option> <option value="telegram_channel">Telegram</option>
<option value="x_account">X (Twitter)</option> <option value="x_account">X (Twitter)</option>
<option value="podcast_feed">Podcast</option>
<option value="excluded">Von mir ausgeschlossen</option> <option value="excluded">Von mir ausgeschlossen</option>
</select> </select>
<label for="sources-filter-category" class="sr-only" data-i18n="sources_modal.filter.category">Kategorie filtern</label> <label for="sources-filter-category" class="sr-only" data-i18n="sources_modal.filter.category">Kategorie filtern</label>
@@ -806,7 +807,7 @@
<script src="/static/js/i18n.js?v=20260513a"></script> <script src="/static/js/i18n.js?v=20260513a"></script>
<script src="/static/js/api.js?v=20260423a"></script> <script src="/static/js/api.js?v=20260423a"></script>
<script src="/static/js/ws.js?v=20260316b"></script> <script src="/static/js/ws.js?v=20260316b"></script>
<script src="/static/js/components.js?v=20260522a"></script> <script src="/static/js/components.js?v=20260522b"></script>
<script src="/static/js/layout.js?v=20260513f"></script> <script src="/static/js/layout.js?v=20260513f"></script>
<script src="/static/js/pipeline.js?v=20260513d"></script> <script src="/static/js/pipeline.js?v=20260513d"></script>
<script src="/static/js/app.js?v=20260522a"></script> <script src="/static/js/app.js?v=20260522a"></script>

Datei anzeigen

@@ -1210,6 +1210,10 @@ const UI = {
/** /**
* Domain-Gruppe rendern (aufklappbar mit Feeds). * Domain-Gruppe rendern (aufklappbar mit Feeds).
*/ */
_sourceTypeLabel(type) {
return ({ rss_feed: 'RSS', web_source: 'Web', telegram_channel: 'Telegram', x_account: 'X', podcast_feed: 'Podcast', excluded: 'Ausgeschlossen' })[type] || 'Web';
},
renderSourceGroup(domain, feeds, isExcluded, excludedNotes, isGlobal) { renderSourceGroup(domain, feeds, isExcluded, excludedNotes, isGlobal) {
const catLabel = this._categoryLabels[feeds[0]?.category] || feeds[0]?.category || ''; const catLabel = this._categoryLabels[feeds[0]?.category] || feeds[0]?.category || '';
const feedCount = feeds.filter(f => f.source_type !== 'excluded').length; const feedCount = feeds.filter(f => f.source_type !== 'excluded').length;
@@ -1244,7 +1248,7 @@ const UI = {
realFeeds.forEach((feed, i) => { realFeeds.forEach((feed, i) => {
const isLast = i === realFeeds.length - 1; const isLast = i === realFeeds.length - 1;
const connector = isLast ? '\u2514\u2500' : '\u251C\u2500'; const connector = isLast ? '\u2514\u2500' : '\u251C\u2500';
const typeLabel = feed.source_type === 'rss_feed' ? 'RSS' : 'Web'; const typeLabel = this._sourceTypeLabel(feed.source_type);
const urlDisplay = feed.url ? this._shortenUrl(feed.url) : ''; const urlDisplay = feed.url ? this._shortenUrl(feed.url) : '';
feedRows += `<div class="source-feed-row"> feedRows += `<div class="source-feed-row">
<span class="source-feed-connector">${connector}</span> <span class="source-feed-connector">${connector}</span>
@@ -1273,7 +1277,7 @@ const UI = {
|| firstFeed.country_code || firstFeed.country_code
|| (Array.isArray(firstFeed.alignments) && firstFeed.alignments.length > 0); || (Array.isArray(firstFeed.alignments) && firstFeed.alignments.length > 0);
if (hasInfo) { if (hasInfo) {
const typeMap = { rss_feed: 'RSS-Feed', web_source: 'Web-Quelle', telegram_channel: 'Telegram-Kanal', podcast_feed: 'Podcast' }; const typeMap = { rss_feed: 'RSS-Feed', web_source: 'Web-Quelle', telegram_channel: 'Telegram-Kanal', x_account: 'X (Twitter)', podcast_feed: 'Podcast' };
const lines = []; const lines = [];
lines.push('Typ: ' + (typeMap[firstFeed.source_type] || firstFeed.source_type || 'Unbekannt')); lines.push('Typ: ' + (typeMap[firstFeed.source_type] || firstFeed.source_type || 'Unbekannt'));
if (firstFeed.language) lines.push('Sprache: ' + firstFeed.language); if (firstFeed.language) lines.push('Sprache: ' + firstFeed.language);
@@ -1314,6 +1318,7 @@ const UI = {
<div class="source-group-info"> <div class="source-group-info">
<span class="source-group-name">${this.escape(displayName)}</span>${infoButtonHtml} <span class="source-group-name">${this.escape(displayName)}</span>${infoButtonHtml}
</div> </div>
${!hasMultiple ? `<span class="source-type-badge type-${feeds[0]?.source_type || ''}">${this._sourceTypeLabel(feeds[0]?.source_type)}</span>` : ''}
<span class="source-category-badge cat-${feeds[0]?.category || 'sonstige'}">${catLabel}</span> <span class="source-category-badge cat-${feeds[0]?.category || 'sonstige'}">${catLabel}</span>
${classificationBadges ? `<span class="source-classification-badges">${classificationBadges}</span>` : ''} ${classificationBadges ? `<span class="source-classification-badges">${classificationBadges}</span>` : ''}
${feedCountBadge} ${feedCountBadge}