comma split
This commit is contained in:
parent
6fdf8f6436
commit
be855415d5
|
|
@ -2,38 +2,68 @@ import React, { useState } from 'react';
|
|||
import { FiSlash, FiPlus, FiTrash2, FiShield } from 'react-icons/fi';
|
||||
|
||||
const BlockedSenders = ({ rule, onUpdate }) => {
|
||||
// 'rule' ist hier das Objekt { email_address, blocked_patterns: [] }
|
||||
const [patterns, setPatterns] = useState(rule?.blocked_patterns || []);
|
||||
const [newPattern, setNewPattern] = useState('');
|
||||
const [inputError, setInputError] = useState('');
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const validatePattern = (pattern) => {
|
||||
// Einfache Validierung: Muss mindestens 3 Zeichen haben und darf nicht leer sein.
|
||||
// Wildcards * sind erlaubt.
|
||||
// Einfache Validierung: Mindestens 3 Zeichen. Wildcards * sind erlaubt.
|
||||
return pattern.length >= 3;
|
||||
};
|
||||
|
||||
const handleAddPattern = () => {
|
||||
const trimmedPattern = newPattern.trim();
|
||||
if (!trimmedPattern) {
|
||||
setInputError('Pattern is required');
|
||||
if (!newPattern.trim()) {
|
||||
setInputError('Please enter a pattern');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!validatePattern(trimmedPattern)) {
|
||||
setInputError('Pattern too short or invalid');
|
||||
// NEU: Splitten am Komma, bereinigen und leere Einträge filtern
|
||||
const potentialPatterns = newPattern
|
||||
.split(',')
|
||||
.map(p => p.trim())
|
||||
.filter(p => p.length > 0);
|
||||
|
||||
const validNewPatterns = [];
|
||||
let duplicateCount = 0;
|
||||
let invalidCount = 0;
|
||||
|
||||
potentialPatterns.forEach(pattern => {
|
||||
// Validierung prüfen
|
||||
if (!validatePattern(pattern)) {
|
||||
invalidCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (patterns.includes(trimmedPattern)) {
|
||||
setInputError('This pattern is already in the list');
|
||||
// Duplikate prüfen (sowohl in bestehender Liste als auch in der neuen Charge)
|
||||
if (patterns.includes(pattern) || validNewPatterns.includes(pattern)) {
|
||||
duplicateCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
setPatterns([...patterns, trimmedPattern]);
|
||||
validNewPatterns.push(pattern);
|
||||
});
|
||||
|
||||
// Fehlerbehandlung: Wenn gar nichts hinzugefügt werden kann
|
||||
if (validNewPatterns.length === 0) {
|
||||
if (invalidCount > 0 && potentialPatterns.length === invalidCount) {
|
||||
setInputError('All entered patterns were invalid (too short).');
|
||||
} else if (duplicateCount > 0) {
|
||||
setInputError('All entered patterns are already in the list.');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// State aktualisieren
|
||||
setPatterns([...patterns, ...validNewPatterns]);
|
||||
setNewPattern('');
|
||||
|
||||
// Optional: Feedback bei teilweisem Erfolg
|
||||
if (invalidCount > 0 || duplicateCount > 0) {
|
||||
setInputError(`Added ${validNewPatterns.length} patterns. (${invalidCount} invalid, ${duplicateCount} duplicates skipped)`);
|
||||
} else {
|
||||
setInputError('');
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemovePattern = (patternToRemove) => {
|
||||
|
|
@ -64,7 +94,7 @@ const BlockedSenders = ({ rule, onUpdate }) => {
|
|||
{/* Add Pattern Form */}
|
||||
<div>
|
||||
<label htmlFor="block-pattern" className="block text-sm font-semibold text-gray-700 mb-2">
|
||||
Block Sender Pattern
|
||||
Block Sender Pattern(s)
|
||||
</label>
|
||||
<div className="flex gap-2">
|
||||
<div className="flex-1">
|
||||
|
|
@ -74,14 +104,17 @@ const BlockedSenders = ({ rule, onUpdate }) => {
|
|||
value={newPattern}
|
||||
onChange={(e) => {
|
||||
setNewPattern(e.target.value);
|
||||
setInputError('');
|
||||
// Fehler nur löschen, wenn User tippt und keine Erfolgsmeldung angezeigt wird
|
||||
if (!inputError.startsWith('Added')) setInputError('');
|
||||
}}
|
||||
onKeyPress={handleKeyPress}
|
||||
placeholder="spam@*.com, *@badsite.org"
|
||||
className={`input-field ${inputError ? 'border-red-500 focus:ring-red-500' : ''}`}
|
||||
placeholder="spam@*.com, *@badsite.org (comma separated)"
|
||||
className={`input-field ${inputError && !inputError.startsWith('Added') ? 'border-red-500 focus:ring-red-500' : ''}`}
|
||||
/>
|
||||
{inputError && (
|
||||
<p className="mt-1 text-sm text-red-600">{inputError}</p>
|
||||
<p className={`mt-1 text-sm ${inputError.startsWith('Added') ? 'text-green-600' : 'text-red-600'}`}>
|
||||
{inputError}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
|
|
@ -93,7 +126,7 @@ const BlockedSenders = ({ rule, onUpdate }) => {
|
|||
</button>
|
||||
</div>
|
||||
<p className="mt-2 text-xs text-gray-500">
|
||||
Supports wildcards (*). Examples: <code>marketing@spam.com</code>, <code>*@phishing.net</code>
|
||||
Paste a comma-separated list to add multiple entries at once. Supports wildcards (*).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
@ -103,6 +136,14 @@ const BlockedSenders = ({ rule, onUpdate }) => {
|
|||
<label className="block text-sm font-semibold text-gray-700">
|
||||
Blocked Patterns ({patterns.length})
|
||||
</label>
|
||||
{patterns.length > 0 && (
|
||||
<button
|
||||
onClick={() => setPatterns([])}
|
||||
className="text-xs text-red-600 hover:text-red-800 hover:underline"
|
||||
>
|
||||
Clear all
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{patterns.length === 0 ? (
|
||||
|
|
@ -112,10 +153,10 @@ const BlockedSenders = ({ rule, onUpdate }) => {
|
|||
<p className="text-sm text-gray-500 mt-1">Add a pattern above to block incoming emails</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-2 max-h-[400px] overflow-y-auto pr-2 custom-scrollbar">
|
||||
{patterns.map((pattern, index) => (
|
||||
<div
|
||||
key={index}
|
||||
key={`${pattern}-${index}`}
|
||||
className="flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg hover:border-red-300 transition-colors group"
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
|
|
|
|||
Loading…
Reference in New Issue