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:
@@ -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>
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
In neuem Issue referenzieren
Einen Benutzer sperren