Fix moderation queue tab switch reload

This commit is contained in:
gpt-engineer-app[bot]
2025-10-11 17:20:35 +00:00
parent f9e12596c7
commit 10950a4034
3 changed files with 42 additions and 8 deletions

View File

@@ -157,13 +157,15 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
getAdminPanelPollInterval, getAdminPanelPollInterval,
getAutoRefreshStrategy, getAutoRefreshStrategy,
getPreserveInteractionState, getPreserveInteractionState,
getUseRealtimeQueue getUseRealtimeQueue,
getRefreshOnTabVisible
} = useAdminSettings(); } = useAdminSettings();
const refreshMode = getAdminPanelRefreshMode(); const refreshMode = getAdminPanelRefreshMode();
const pollInterval = getAdminPanelPollInterval(); const pollInterval = getAdminPanelPollInterval();
const refreshStrategy = getAutoRefreshStrategy(); const refreshStrategy = getAutoRefreshStrategy();
const preserveInteraction = getPreserveInteractionState(); const preserveInteraction = getPreserveInteractionState();
const useRealtimeQueue = getUseRealtimeQueue(); const useRealtimeQueue = getUseRealtimeQueue();
const refreshOnTabVisible = getRefreshOnTabVisible();
// Track recently removed items to prevent realtime override of optimistic updates // Track recently removed items to prevent realtime override of optimistic updates
const recentlyRemovedRef = useRef<Set<string>>(new Set()); const recentlyRemovedRef = useRef<Set<string>>(new Set());
@@ -172,6 +174,8 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
// Store admin settings and stable refs to avoid triggering fetchItems recreation // Store admin settings and stable refs to avoid triggering fetchItems recreation
const refreshStrategyRef = useRef(refreshStrategy); const refreshStrategyRef = useRef(refreshStrategy);
const preserveInteractionRef = useRef(preserveInteraction); const preserveInteractionRef = useRef(preserveInteraction);
const refreshOnTabVisibleRef = useRef(refreshOnTabVisible);
const activeTabRef = useRef<QueueTab>(activeTab);
const userRef = useRef(user); const userRef = useRef(user);
const toastRef = useRef(toast); const toastRef = useRef(toast);
const isAdminRef = useRef(isAdmin); const isAdminRef = useRef(isAdmin);
@@ -180,11 +184,17 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
useEffect(() => { useEffect(() => {
refreshStrategyRef.current = refreshStrategy; refreshStrategyRef.current = refreshStrategy;
preserveInteractionRef.current = preserveInteraction; preserveInteractionRef.current = preserveInteraction;
refreshOnTabVisibleRef.current = refreshOnTabVisible;
userRef.current = user; userRef.current = user;
toastRef.current = toast; toastRef.current = toast;
isAdminRef.current = isAdmin; isAdminRef.current = isAdmin;
isSuperuserRef.current = isSuperuser; isSuperuserRef.current = isSuperuser;
}, [refreshStrategy, preserveInteraction, user, toast, isAdmin, isSuperuser]); }, [refreshStrategy, preserveInteraction, refreshOnTabVisible, user, toast, isAdmin, isSuperuser]);
// Sync activeTab with ref
useEffect(() => {
activeTabRef.current = activeTab;
}, [activeTab]);
// Persist sort configuration // Persist sort configuration
useEffect(() => { useEffect(() => {
@@ -1165,7 +1175,7 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
}; };
}, [user, useRealtimeQueue, debouncedRealtimeUpdate]); }, [user, useRealtimeQueue, debouncedRealtimeUpdate]);
// Visibility change handler - pause queue updates when tab is hidden // Visibility change handler - smart tab switching behavior
useEffect(() => { useEffect(() => {
const handleVisibilityChange = () => { const handleVisibilityChange = () => {
if (document.hidden) { if (document.hidden) {
@@ -1174,17 +1184,23 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
} else { } else {
console.log('📱 Tab visible - resuming queue updates'); console.log('📱 Tab visible - resuming queue updates');
pauseFetchingRef.current = false; pauseFetchingRef.current = false;
// Optional: trigger single refresh when tab becomes visible
if (initialFetchCompleteRef.current && !isMountingRef.current) { // Check admin setting for auto-refresh behavior
console.log('🔄 Tab became visible - triggering refresh'); const shouldRefresh = refreshOnTabVisibleRef.current;
fetchItems(filtersRef.current.entityFilter, filtersRef.current.statusFilter, true, activeTab);
if (shouldRefresh && initialFetchCompleteRef.current && !isMountingRef.current) {
console.log('🔄 Tab became visible - triggering refresh (admin setting enabled)');
fetchItems(filtersRef.current.entityFilter, filtersRef.current.statusFilter, true, activeTabRef.current);
} else {
console.log('✅ Tab became visible - resuming without refresh');
// Realtime subscriptions will handle updates naturally
} }
} }
}; };
document.addEventListener('visibilitychange', handleVisibilityChange); document.addEventListener('visibilitychange', handleVisibilityChange);
return () => document.removeEventListener('visibilitychange', handleVisibilityChange); return () => document.removeEventListener('visibilitychange', handleVisibilityChange);
}, [fetchItems, activeTab]); }, []); // Empty deps - all values come from refs
const handleResetToPending = async (item: ModerationItem) => { const handleResetToPending = async (item: ModerationItem) => {
setActionLoading(item.id); setActionLoading(item.id);

View File

@@ -157,6 +157,12 @@ export function useAdminSettings() {
return cleanValue === 'true' || cleanValue === true; return cleanValue === 'true' || cleanValue === true;
}; };
const getRefreshOnTabVisible = (): boolean => {
const value = getSettingValue('system.refresh_on_tab_visible', 'false');
const cleanValue = typeof value === 'string' ? value.replace(/"/g, '') : value;
return cleanValue === 'true' || cleanValue === true;
};
return { return {
settings, settings,
isLoading, isLoading,
@@ -180,5 +186,6 @@ export function useAdminSettings() {
getAutoRefreshStrategy, getAutoRefreshStrategy,
getPreserveInteractionState, getPreserveInteractionState,
getUseRealtimeQueue, getUseRealtimeQueue,
getRefreshOnTabVisible,
}; };
} }

View File

@@ -0,0 +1,11 @@
-- Add admin setting to control auto-refresh on tab visibility change
INSERT INTO admin_settings (setting_key, setting_value, category, description, created_at, updated_at)
VALUES (
'system.refresh_on_tab_visible',
'false',
'system',
'Auto-refresh moderation queue when returning to tab (default: false, realtime handles updates)',
now(),
now()
)
ON CONFLICT (setting_key) DO NOTHING;