Fix: Always show autocompact threshold ui (#5701)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -27,19 +27,17 @@ const alertStyles: Record<AlertType, string> = {
|
|||||||
export const AlertBox = ({ alert, className }: AlertBoxProps) => {
|
export const AlertBox = ({ alert, className }: AlertBoxProps) => {
|
||||||
const { read } = useConfig();
|
const { read } = useConfig();
|
||||||
const [isEditingThreshold, setIsEditingThreshold] = useState(false);
|
const [isEditingThreshold, setIsEditingThreshold] = useState(false);
|
||||||
const [loadedThreshold, setLoadedThreshold] = useState<number | null>(null);
|
const [loadedThreshold, setLoadedThreshold] = useState<number>(0.8);
|
||||||
const [thresholdValue, setThresholdValue] = useState(
|
const [thresholdValue, setThresholdValue] = useState(80);
|
||||||
alert.autoCompactThreshold ? Math.max(1, Math.round(alert.autoCompactThreshold * 100)) : 80
|
|
||||||
);
|
|
||||||
const [isSaving, setIsSaving] = useState(false);
|
const [isSaving, setIsSaving] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadThreshold = async () => {
|
const loadThreshold = async () => {
|
||||||
try {
|
try {
|
||||||
const threshold = await read('GOOSE_AUTO_COMPACT_THRESHOLD', false);
|
const threshold = await read('GOOSE_AUTO_COMPACT_THRESHOLD', false);
|
||||||
if (threshold !== undefined && threshold !== null) {
|
if (threshold !== undefined && threshold !== null && typeof threshold === 'number') {
|
||||||
setLoadedThreshold(threshold as number);
|
setLoadedThreshold(threshold);
|
||||||
setThresholdValue(Math.max(1, Math.round((threshold as number) * 100)));
|
setThresholdValue(Math.max(1, Math.round(threshold * 100)));
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error fetching auto-compact threshold:', err);
|
console.error('Error fetching auto-compact threshold:', err);
|
||||||
@@ -49,7 +47,7 @@ export const AlertBox = ({ alert, className }: AlertBoxProps) => {
|
|||||||
loadThreshold();
|
loadThreshold();
|
||||||
}, [read]);
|
}, [read]);
|
||||||
|
|
||||||
const currentThreshold = loadedThreshold !== null ? loadedThreshold : alert.autoCompactThreshold;
|
const currentThreshold = loadedThreshold;
|
||||||
|
|
||||||
const handleSaveThreshold = async () => {
|
const handleSaveThreshold = async () => {
|
||||||
if (isSaving) return; // Prevent double-clicks
|
if (isSaving) return; // Prevent double-clicks
|
||||||
@@ -103,95 +101,91 @@ export const AlertBox = ({ alert, className }: AlertBoxProps) => {
|
|||||||
<span className="text-[11px]">{alert.message}</span>
|
<span className="text-[11px]">{alert.message}</span>
|
||||||
|
|
||||||
{/* Auto-compact threshold indicator with edit */}
|
{/* Auto-compact threshold indicator with edit */}
|
||||||
{currentThreshold !== undefined && (
|
<div className="flex items-center justify-center gap-1 min-h-[20px]">
|
||||||
<div className="flex items-center justify-center gap-1 min-h-[20px]">
|
{isEditingThreshold ? (
|
||||||
{isEditingThreshold ? (
|
<>
|
||||||
<>
|
<span className="text-[10px] opacity-70">Auto compact at</span>
|
||||||
<span className="text-[10px] opacity-70">Auto compact at</span>
|
<input
|
||||||
<input
|
type="number"
|
||||||
type="number"
|
min="1"
|
||||||
min="1"
|
max="100"
|
||||||
max="100"
|
step="1"
|
||||||
step="1"
|
value={thresholdValue}
|
||||||
value={thresholdValue}
|
onChange={(e) => {
|
||||||
onChange={(e) => {
|
const val = parseInt(e.target.value, 10);
|
||||||
const val = parseInt(e.target.value, 10);
|
// Allow empty input for easier editing
|
||||||
// Allow empty input for easier editing
|
if (e.target.value === '') {
|
||||||
if (e.target.value === '') {
|
setThresholdValue(1);
|
||||||
setThresholdValue(1);
|
} else if (!isNaN(val)) {
|
||||||
} else if (!isNaN(val)) {
|
// Clamp value between 1 and 100
|
||||||
// Clamp value between 1 and 100
|
setThresholdValue(Math.max(1, Math.min(100, val)));
|
||||||
setThresholdValue(Math.max(1, Math.min(100, val)));
|
}
|
||||||
}
|
}}
|
||||||
}}
|
onBlur={(e) => {
|
||||||
onBlur={(e) => {
|
// On blur, ensure we have a valid value
|
||||||
// On blur, ensure we have a valid value
|
const val = parseInt(e.target.value, 10);
|
||||||
const val = parseInt(e.target.value, 10);
|
if (isNaN(val) || val < 1) {
|
||||||
if (isNaN(val) || val < 1) {
|
setThresholdValue(1);
|
||||||
setThresholdValue(1);
|
} else if (val > 100) {
|
||||||
} else if (val > 100) {
|
setThresholdValue(100);
|
||||||
setThresholdValue(100);
|
}
|
||||||
}
|
}}
|
||||||
}}
|
onKeyDown={(e) => {
|
||||||
onKeyDown={(e) => {
|
if (e.key === 'Enter') {
|
||||||
if (e.key === 'Enter') {
|
|
||||||
handleSaveThreshold();
|
|
||||||
} else if (e.key === 'Escape') {
|
|
||||||
setIsEditingThreshold(false);
|
|
||||||
const resetValue = currentThreshold
|
|
||||||
? Math.round(currentThreshold * 100)
|
|
||||||
: 80;
|
|
||||||
setThresholdValue(Math.max(1, resetValue));
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onFocus={(e) => {
|
|
||||||
// Select all text on focus for easier editing
|
|
||||||
e.target.select();
|
|
||||||
}}
|
|
||||||
onClick={(e) => {
|
|
||||||
// Prevent issues with text selection
|
|
||||||
e.stopPropagation();
|
|
||||||
}}
|
|
||||||
className="w-12 px-1 text-[10px] bg-white/10 border border-current/30 rounded outline-none text-center focus:bg-white/20 focus:border-current/50 transition-colors"
|
|
||||||
disabled={isSaving}
|
|
||||||
autoFocus
|
|
||||||
/>
|
|
||||||
<span className="text-[10px] opacity-70">%</span>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onMouseDown={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
handleSaveThreshold();
|
handleSaveThreshold();
|
||||||
}}
|
} else if (e.key === 'Escape') {
|
||||||
disabled={isSaving}
|
setIsEditingThreshold(false);
|
||||||
className="p-1 hover:opacity-60 transition-opacity cursor-pointer relative z-50"
|
const resetValue = Math.round(currentThreshold * 100);
|
||||||
style={{ minWidth: '20px', minHeight: '20px', pointerEvents: 'auto' }}
|
setThresholdValue(Math.max(1, resetValue));
|
||||||
>
|
}
|
||||||
<FaSave className="w-3 h-3" />
|
}}
|
||||||
</button>
|
onFocus={(e) => {
|
||||||
</>
|
// Select all text on focus for easier editing
|
||||||
) : (
|
e.target.select();
|
||||||
<>
|
}}
|
||||||
<span className="text-[10px] opacity-70">
|
onClick={(e) => {
|
||||||
Auto compact at {Math.round(currentThreshold * 100)}%
|
// Prevent issues with text selection
|
||||||
</span>
|
e.stopPropagation();
|
||||||
<button
|
}}
|
||||||
type="button"
|
className="w-12 px-1 text-[10px] bg-white/10 border border-current/30 rounded outline-none text-center focus:bg-white/20 focus:border-current/50 transition-colors"
|
||||||
onClick={(e) => {
|
disabled={isSaving}
|
||||||
e.preventDefault();
|
autoFocus
|
||||||
e.stopPropagation();
|
/>
|
||||||
setIsEditingThreshold(true);
|
<span className="text-[10px] opacity-70">%</span>
|
||||||
}}
|
<button
|
||||||
className="p-1 hover:opacity-60 transition-opacity cursor-pointer relative z-10"
|
type="button"
|
||||||
style={{ minWidth: '20px', minHeight: '20px' }}
|
onMouseDown={(e) => {
|
||||||
>
|
e.preventDefault();
|
||||||
<FaPencilAlt className="w-3 h-3 opacity-70" />
|
e.stopPropagation();
|
||||||
</button>
|
handleSaveThreshold();
|
||||||
</>
|
}}
|
||||||
)}
|
disabled={isSaving}
|
||||||
</div>
|
className="p-1 hover:opacity-60 transition-opacity cursor-pointer relative z-50"
|
||||||
)}
|
style={{ minWidth: '20px', minHeight: '20px', pointerEvents: 'auto' }}
|
||||||
|
>
|
||||||
|
<FaSave className="w-3 h-3" />
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<span className="text-[10px] opacity-70">
|
||||||
|
Auto compact at {Math.round(currentThreshold * 100)}%
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
setIsEditingThreshold(true);
|
||||||
|
}}
|
||||||
|
className="p-1 hover:opacity-60 transition-opacity cursor-pointer relative z-10"
|
||||||
|
style={{ minWidth: '20px', minHeight: '20px' }}
|
||||||
|
>
|
||||||
|
<FaPencilAlt className="w-3 h-3 opacity-70" />
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="flex justify-between w-full relative">
|
<div className="flex justify-between w-full relative">
|
||||||
{(() => {
|
{(() => {
|
||||||
|
|||||||
@@ -20,6 +20,5 @@ export interface Alert {
|
|||||||
compactButtonDisabled?: boolean;
|
compactButtonDisabled?: boolean;
|
||||||
onCompact?: () => void;
|
onCompact?: () => void;
|
||||||
compactIcon?: React.ReactNode;
|
compactIcon?: React.ReactNode;
|
||||||
autoCompactThreshold?: number;
|
|
||||||
onThresholdChange?: (threshold: number) => void;
|
onThresholdChange?: (threshold: number) => void;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user