Wording: Domain sperren → Domain ausschließen

Einheitliche Umbenennung in UI-Texten, Kommentaren und Docstrings:
- Sperren → Ausschließen
- Gesperrt → Ausgeschlossen
- Entsperren → Ausschluss aufheben

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dieser Commit ist enthalten in:
claude-dev
2026-03-08 14:02:36 +01:00
Ursprung 2dd11c9db7
Commit 18954cf70e
6 geänderte Dateien mit 25 neuen und 25 gelöschten Zeilen

Datei anzeigen

@@ -150,7 +150,7 @@ class DiscoverMultiResponse(BaseModel):
fallback_single: bool = False fallback_single: bool = False
# Domain-Aktionen (Sperren/Entsperren) # Domain-Aktionen (Ausschließen/Ausschluss aufheben)
class DomainActionRequest(BaseModel): class DomainActionRequest(BaseModel):
domain: str = Field(min_length=1, max_length=200) domain: str = Field(min_length=1, max_length=200)
notes: Optional[str] = None notes: Optional[str] = None

Datei anzeigen

@@ -291,7 +291,7 @@ async def block_domain(
current_user: dict = Depends(get_current_user), current_user: dict = Depends(get_current_user),
db: aiosqlite.Connection = Depends(db_dependency), db: aiosqlite.Connection = Depends(db_dependency),
): ):
"""Domain sperren: Alle Feeds deaktivieren + excluded-Eintrag anlegen.""" """Domain ausschließen: Alle Feeds deaktivieren + excluded-Eintrag anlegen."""
tenant_id = current_user.get("tenant_id") tenant_id = current_user.get("tenant_id")
domain = data.domain.lower().strip() domain = data.domain.lower().strip()
username = current_user["username"] username = current_user["username"]
@@ -351,7 +351,7 @@ async def unblock_domain(
current_user: dict = Depends(get_current_user), current_user: dict = Depends(get_current_user),
db: aiosqlite.Connection = Depends(db_dependency), db: aiosqlite.Connection = Depends(db_dependency),
): ):
"""Domain entsperren: excluded-Eintrag loeschen + Feeds reaktivieren.""" """Domain-Ausschluss aufheben: excluded-Eintrag loeschen + Feeds reaktivieren."""
tenant_id = current_user.get("tenant_id") tenant_id = current_user.get("tenant_id")
domain = data.domain.lower().strip() domain = data.domain.lower().strip()
@@ -374,7 +374,7 @@ async def unblock_domain(
feeds_reactivated = cursor.rowcount feeds_reactivated = cursor.rowcount
else: else:
await db.execute( await db.execute(
"""UPDATE sources SET source_type = 'web_source', status = 'active', notes = 'Entsperrt' """UPDATE sources SET source_type = 'web_source', status = 'active', notes = 'Ausschluss aufgehoben'
WHERE LOWER(domain) = ? AND source_type = 'excluded' AND (tenant_id IS NULL OR tenant_id = ?)""", WHERE LOWER(domain) = ? AND source_type = 'excluded' AND (tenant_id IS NULL OR tenant_id = ?)""",
(domain, tenant_id), (domain, tenant_id),
) )

Datei anzeigen

@@ -3437,7 +3437,7 @@ a:hover {
gap: var(--sp-xs); gap: var(--sp-xs);
} }
/* Gesperrte Domain */ /* Ausgeschlossene Domain */
.source-group-header.excluded { .source-group-header.excluded {
grid-template-columns: 1fr auto auto; grid-template-columns: 1fr auto auto;
border-left: 3px solid var(--error); border-left: 3px solid var(--error);

Datei anzeigen

@@ -427,7 +427,7 @@
<option value="">Alle Typen</option> <option value="">Alle Typen</option>
<option value="rss_feed">RSS-Feed</option> <option value="rss_feed">RSS-Feed</option>
<option value="web_source">Web-Quelle</option> <option value="web_source">Web-Quelle</option>
<option value="excluded">Gesperrt</option> <option value="excluded">Ausgeschlossen</option>
</select> </select>
<label for="sources-filter-category" class="sr-only">Kategorie filtern</label> <label for="sources-filter-category" class="sr-only">Kategorie filtern</label>
<select id="sources-filter-category" class="timeline-filter-select" onchange="App.filterSources()"> <select id="sources-filter-category" class="timeline-filter-select" onchange="App.filterSources()">
@@ -447,12 +447,12 @@
<input type="text" id="sources-search" class="timeline-filter-input sources-search-input" placeholder="Suche..." oninput="App.filterSources()"> <input type="text" id="sources-search" class="timeline-filter-input sources-search-input" placeholder="Suche..." oninput="App.filterSources()">
</div> </div>
<div class="sources-toolbar-actions"> <div class="sources-toolbar-actions">
<button class="btn btn-secondary btn-small source-block-btn" onclick="App.showBlockDomainDialog()">Domain sperren</button> <button class="btn btn-secondary btn-small source-block-btn" onclick="App.showBlockDomainDialog()">Domain ausschließen</button>
<button class="btn btn-primary btn-small" onclick="App.toggleSourceForm()">+ Quelle</button> <button class="btn btn-primary btn-small" onclick="App.toggleSourceForm()">+ Quelle</button>
</div> </div>
</div> </div>
<!-- Inline-Formular: Domain sperren (ein-/ausklappbar) --> <!-- Inline-Formular: Domain ausschließen (ein-/ausklappbar) -->
<div class="sources-add-form" id="sources-block-form" style="display:none;"> <div class="sources-add-form" id="sources-block-form" style="display:none;">
<div class="sources-form-row"> <div class="sources-form-row">
<div class="form-group flex-1"> <div class="form-group flex-1">
@@ -463,7 +463,7 @@
<label for="block-domain-notes">Notizen</label> <label for="block-domain-notes">Notizen</label>
<input type="text" id="block-domain-notes" class="source-notes-input" placeholder="Optional"> <input type="text" id="block-domain-notes" class="source-notes-input" placeholder="Optional">
</div> </div>
<button class="btn btn-danger btn-small" onclick="App.blockDomain()">Sperren</button> <button class="btn btn-danger btn-small" onclick="App.blockDomain()">Ausschließen</button>
<button class="btn btn-secondary btn-small" onclick="App.showBlockDomainDialog(false)">Abbrechen</button> <button class="btn btn-secondary btn-small" onclick="App.showBlockDomainDialog(false)">Abbrechen</button>
</div> </div>
</div> </div>

Datei anzeigen

@@ -2199,7 +2199,7 @@ const App = {
bar.innerHTML = ` bar.innerHTML = `
<span class="sources-stat-item"><span class="sources-stat-value">${rss.count}</span> RSS-Feeds</span> <span class="sources-stat-item"><span class="sources-stat-value">${rss.count}</span> RSS-Feeds</span>
<span class="sources-stat-item"><span class="sources-stat-value">${web.count}</span> Web-Quellen</span> <span class="sources-stat-item"><span class="sources-stat-value">${web.count}</span> Web-Quellen</span>
<span class="sources-stat-item"><span class="sources-stat-value">${excluded}</span> Gesperrt</span> <span class="sources-stat-item"><span class="sources-stat-value">${excluded}</span> Ausgeschlossen</span>
<span class="sources-stat-item"><span class="sources-stat-value">${stats.total_articles}</span> Artikel gesamt</span> <span class="sources-stat-item"><span class="sources-stat-value">${stats.total_articles}</span> Artikel gesamt</span>
`; `;
}, },
@@ -2237,7 +2237,7 @@ const App = {
groups.get(domain).push(s); groups.get(domain).push(s);
}); });
// Gesperrte Domains die keine Feeds haben auch als Gruppe // Ausgeschlossene Domains die keine Feeds haben auch als Gruppe
this._blacklistOnly.forEach(s => { this._blacklistOnly.forEach(s => {
const domain = (s.domain || s.name || '').toLowerCase(); const domain = (s.domain || s.name || '').toLowerCase();
if (domain && !groups.has(domain)) { if (domain && !groups.has(domain)) {
@@ -2279,7 +2279,7 @@ const App = {
return; return;
} }
// Sortierung: Aktive zuerst (alphabetisch), dann gesperrte // Sortierung: Aktive zuerst (alphabetisch), dann ausgeschlossene
filteredGroups.sort((a, b) => { filteredGroups.sort((a, b) => {
if (a.isExcluded !== b.isExcluded) return a.isExcluded ? 1 : -1; if (a.isExcluded !== b.isExcluded) return a.isExcluded ? 1 : -1;
return a.domain.localeCompare(b.domain); return a.domain.localeCompare(b.domain);
@@ -2364,7 +2364,7 @@ const App = {
}, },
/** /**
* Domain sperren (aus dem Inline-Formular). * Domain ausschließen (aus dem Inline-Formular).
*/ */
async blockDomain() { async blockDomain() {
const input = document.getElementById('block-domain-input'); const input = document.getElementById('block-domain-input');
@@ -2378,7 +2378,7 @@ const App = {
try { try {
await API.blockDomain(domain, notes); await API.blockDomain(domain, notes);
UI.showToast(`${domain} gesperrt.`, 'success'); UI.showToast(`${domain} ausgeschlossen.`, 'success');
this.showBlockDomainDialog(false); this.showBlockDomainDialog(false);
await this.loadSources(); await this.loadSources();
this.updateSidebarStats(); this.updateSidebarStats();
@@ -2437,10 +2437,10 @@ const App = {
}, },
/** /**
* Domain direkt sperren (aus der Gruppenliste). * Domain direkt ausschließen (aus der Gruppenliste).
*/ */
async blockDomainDirect(domain) { async blockDomainDirect(domain) {
if (!await confirmDialog(`"${domain}" wirklich sperren? Alle Feeds dieser Domain werden deaktiviert.`)) return; if (!await confirmDialog(`"${domain}" wirklich ausschließen? Alle Feeds dieser Domain werden deaktiviert.`)) return;
try { try {
await API.blockDomain(domain); await API.blockDomain(domain);
@@ -2453,12 +2453,12 @@ const App = {
}, },
/** /**
* Domain entsperren. * Domain-Ausschluss aufheben.
*/ */
async unblockDomain(domain) { async unblockDomain(domain) {
try { try {
await API.unblockDomain(domain); await API.unblockDomain(domain);
UI.showToast(`${domain} entsperrt.`, 'success'); UI.showToast(`${domain} Ausschluss aufgehoben.`, 'success');
await this.loadSources(); await this.loadSources();
this.updateSidebarStats(); this.updateSidebarStats();
} catch (err) { } catch (err) {
@@ -2499,7 +2499,7 @@ const App = {
}, },
/** /**
* "Domain sperren" Dialog ein-/ausblenden. * "Domain ausschließen" Dialog ein-/ausblenden.
*/ */
showBlockDomainDialog(show) { showBlockDomainDialog(show) {
const form = document.getElementById('sources-block-form'); const form = document.getElementById('sources-block-form');
@@ -2558,12 +2558,12 @@ const App = {
return; return;
} }
// Prüfen ob Domain gesperrt ist // Prüfen ob Domain ausgeschlossen ist
const inputDomain = url.replace(/^https?:\/\//, '').replace(/^www\./, '').split('/')[0].toLowerCase(); const inputDomain = url.replace(/^https?:\/\//, '').replace(/^www\./, '').split('/')[0].toLowerCase();
const isBlocked = inputDomain && this._blacklistOnly.some(s => (s.domain || '').toLowerCase() === inputDomain); const isBlocked = inputDomain && this._blacklistOnly.some(s => (s.domain || '').toLowerCase() === inputDomain);
if (isBlocked) { if (isBlocked) {
if (!await confirmDialog(`"${inputDomain}" ist gesperrt. Trotzdem hinzufügen? Die Domain wird dabei entsperrt.`)) return; if (!await confirmDialog(`"${inputDomain}" ist ausgeschlossen. Trotzdem hinzufügen? Der Ausschluss wird dabei aufgehoben.`)) return;
await API.unblockDomain(inputDomain); await API.unblockDomain(inputDomain);
} }

Datei anzeigen

@@ -537,16 +537,16 @@ const UI = {
const escapedDomain = this.escape(domain); const escapedDomain = this.escape(domain);
if (isExcluded) { if (isExcluded) {
// Gesperrte Domain // Ausgeschlossene Domain
const notesHtml = excludedNotes ? ` <span class="source-group-notes">${this.escape(excludedNotes)}</span>` : ''; const notesHtml = excludedNotes ? ` <span class="source-group-notes">${this.escape(excludedNotes)}</span>` : '';
return `<div class="source-group"> return `<div class="source-group">
<div class="source-group-header excluded"> <div class="source-group-header excluded">
<div class="source-group-info"> <div class="source-group-info">
<span class="source-group-name">${this.escape(displayName)}</span>${notesHtml} <span class="source-group-name">${this.escape(displayName)}</span>${notesHtml}
</div> </div>
<span class="source-excluded-badge">Gesperrt</span> <span class="source-excluded-badge">Ausgeschlossen</span>
<div class="source-group-actions"> <div class="source-group-actions">
<button class="btn btn-small btn-secondary" onclick="App.unblockDomain('${escapedDomain}')">Entsperren</button> <button class="btn btn-small btn-secondary" onclick="App.unblockDomain('${escapedDomain}')">Ausschluss aufheben</button>
<button class="source-delete-btn" onclick="App.deleteDomain('${escapedDomain}')" title="Löschen" aria-label="Löschen">&times;</button> <button class="source-delete-btn" onclick="App.deleteDomain('${escapedDomain}')" title="Löschen" aria-label="Löschen">&times;</button>
</div> </div>
</div> </div>
@@ -592,7 +592,7 @@ const UI = {
${feedCountBadge} ${feedCountBadge}
<div class="source-group-actions" onclick="event.stopPropagation()"> <div class="source-group-actions" onclick="event.stopPropagation()">
${!hasMultiple && feeds[0]?.id ? `<button class="source-edit-btn" onclick="App.editSource(${feeds[0].id})" title="Bearbeiten" aria-label="Bearbeiten">&#9998;</button>` : ''} ${!hasMultiple && feeds[0]?.id ? `<button class="source-edit-btn" onclick="App.editSource(${feeds[0].id})" title="Bearbeiten" aria-label="Bearbeiten">&#9998;</button>` : ''}
<button class="btn btn-small btn-secondary" onclick="App.blockDomainDirect('${escapedDomain}')">Sperren</button> <button class="btn btn-small btn-secondary" onclick="App.blockDomainDirect('${escapedDomain}')">Ausschließen</button>
<button class="source-delete-btn" onclick="App.deleteDomain('${escapedDomain}')" title="Löschen" aria-label="Löschen">&times;</button> <button class="source-delete-btn" onclick="App.deleteDomain('${escapedDomain}')" title="Löschen" aria-label="Löschen">&times;</button>
</div> </div>
</div> </div>