Merge pull request #169 from Worklenz/imp/task-list-performance-fixes

Imp/task list performance fixes
This commit is contained in:
Chamika J
2025-06-21 18:53:55 +05:30
committed by GitHub
21 changed files with 1735 additions and 452 deletions

View File

@@ -1,5 +1,5 @@
import { ConfigProvider, theme } from 'antd';
import React, { useEffect, useRef } from 'react';
import React, { useEffect, useRef, memo, useMemo, useCallback } from 'react';
import { useAppSelector } from '@/hooks/useAppSelector';
import { useAppDispatch } from '@/hooks/useAppDispatch';
import { initializeTheme } from './themeSlice';
@@ -9,12 +9,45 @@ type ChildrenProp = {
children: React.ReactNode;
};
const ThemeWrapper = ({ children }: ChildrenProp) => {
const ThemeWrapper = memo(({ children }: ChildrenProp) => {
const dispatch = useAppDispatch();
const themeMode = useAppSelector(state => state.themeReducer.mode);
const isInitialized = useAppSelector(state => state.themeReducer.isInitialized);
const configRef = useRef<HTMLDivElement>(null);
// Memoize theme configuration to prevent unnecessary re-renders
const themeConfig = useMemo(() => ({
algorithm: themeMode === 'dark' ? theme.darkAlgorithm : theme.defaultAlgorithm,
components: {
Layout: {
colorBgLayout: themeMode === 'dark' ? colors.darkGray : colors.white,
headerBg: themeMode === 'dark' ? colors.darkGray : colors.white,
},
Menu: {
colorBgContainer: colors.transparent,
},
Table: {
rowHoverBg: themeMode === 'dark' ? '#000' : '#edebf0',
},
Select: {
controlHeight: 32,
},
},
token: {
borderRadius: 4,
},
}), [themeMode]);
// Memoize the theme class name
const themeClassName = useMemo(() => `theme-${themeMode}`, [themeMode]);
// Memoize the media query change handler
const handleMediaQueryChange = useCallback((e: MediaQueryListEvent) => {
if (!localStorage.getItem('theme')) {
dispatch(initializeTheme());
}
}, [dispatch]);
// Initialize theme after mount
useEffect(() => {
if (!isInitialized) {
@@ -26,15 +59,9 @@ const ThemeWrapper = ({ children }: ChildrenProp) => {
useEffect(() => {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handleChange = (e: MediaQueryListEvent) => {
if (!localStorage.getItem('theme')) {
dispatch(initializeTheme());
}
};
mediaQuery.addEventListener('change', handleChange);
return () => mediaQuery.removeEventListener('change', handleChange);
}, [dispatch]);
mediaQuery.addEventListener('change', handleMediaQueryChange);
return () => mediaQuery.removeEventListener('change', handleMediaQueryChange);
}, [handleMediaQueryChange]);
// Add CSS transition classes to prevent flash
useEffect(() => {
@@ -44,34 +71,14 @@ const ThemeWrapper = ({ children }: ChildrenProp) => {
}, []);
return (
<div ref={configRef} className={`theme-${themeMode}`}>
<ConfigProvider
theme={{
algorithm: themeMode === 'dark' ? theme.darkAlgorithm : theme.defaultAlgorithm,
components: {
Layout: {
colorBgLayout: themeMode === 'dark' ? colors.darkGray : colors.white,
headerBg: themeMode === 'dark' ? colors.darkGray : colors.white,
},
Menu: {
colorBgContainer: colors.transparent,
},
Table: {
rowHoverBg: themeMode === 'dark' ? '#000' : '#edebf0',
},
Select: {
controlHeight: 32,
},
},
token: {
borderRadius: 4,
},
}}
>
<div ref={configRef} className={themeClassName}>
<ConfigProvider theme={themeConfig}>
{children}
</ConfigProvider>
</div>
);
};
});
ThemeWrapper.displayName = 'ThemeWrapper';
export default ThemeWrapper;