feat(email-templates): update release note template for Worklenz 2.1.0
- Added a title and meta subject for the release note template. - Enhanced styling for better readability and user experience, including background color, font adjustments, and button styles. - Introduced new sections for features, including a new tasks list, kanban board, group view, language support, and bug fixes. - Improved responsiveness and dark mode support for the email template.
This commit is contained in:
@@ -45,7 +45,7 @@
|
||||
// Determine which tracking ID to use based on the environment
|
||||
const isProduction = window.location.hostname === 'app.worklenz.com';
|
||||
|
||||
const trackingId = isProduction ? 'G-XXXXXXXXXX' : 'G-3LM2HGWEXG'; // Open source tracking ID
|
||||
const trackingId = isProduction ? 'G-7KSRKQ1397' : 'G-3LM2HGWEXG'; // Open source tracking ID
|
||||
|
||||
// Load the Google Analytics script
|
||||
const script = document.createElement('script');
|
||||
|
||||
@@ -26,7 +26,7 @@ const TASK_LIST_MIN_WIDTH = 500;
|
||||
const SIDEBAR_MAX_WIDTH = 400;
|
||||
|
||||
// Lazy load heavy components
|
||||
const TaskDrawer = React.lazy(() => import('@components/task-drawer/task-drawer'));
|
||||
const TaskDrawer = React.lazy(() => import('@/components/task-drawer/task-drawer'));
|
||||
|
||||
const HomePage = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
@@ -35,6 +35,19 @@ const HomePage = memo(() => {
|
||||
|
||||
useDocumentTitle('Home');
|
||||
|
||||
// Preload TaskDrawer component to prevent dynamic import failures
|
||||
useEffect(() => {
|
||||
const preloadTaskDrawer = async () => {
|
||||
try {
|
||||
await import('@/components/task-drawer/task-drawer');
|
||||
} catch (error) {
|
||||
console.warn('Failed to preload TaskDrawer:', error);
|
||||
}
|
||||
};
|
||||
|
||||
preloadTaskDrawer();
|
||||
}, []);
|
||||
|
||||
// Memoize fetch function to prevent recreation on every render
|
||||
const fetchLookups = useCallback(async () => {
|
||||
const fetchPromises = [
|
||||
@@ -113,9 +126,15 @@ const HomePage = memo(() => {
|
||||
|
||||
{MainContent}
|
||||
|
||||
{/* Use Suspense for lazy-loaded components */}
|
||||
<Suspense fallback={null}>
|
||||
{createPortal(<TaskDrawer />, document.body, 'home-task-drawer')}
|
||||
{/* Use Suspense for lazy-loaded components with error boundary */}
|
||||
<Suspense fallback={<div>Loading...</div>}>
|
||||
{createPortal(
|
||||
<React.Suspense fallback={null}>
|
||||
<TaskDrawer />
|
||||
</React.Suspense>,
|
||||
document.body,
|
||||
'home-task-drawer'
|
||||
)}
|
||||
</Suspense>
|
||||
|
||||
{createPortal(
|
||||
|
||||
@@ -379,6 +379,51 @@ const ProjectList: React.FC = () => {
|
||||
}
|
||||
}, [projectsError]);
|
||||
|
||||
// Optimized refresh handler with better error handling
|
||||
const handleRefresh = useCallback(async () => {
|
||||
try {
|
||||
trackMixpanelEvent(evt_projects_refresh_click);
|
||||
setIsLoading(true);
|
||||
setErrorMessage(null);
|
||||
|
||||
if (viewMode === ProjectViewType.LIST) {
|
||||
await refetchProjects();
|
||||
} else if (viewMode === ProjectViewType.GROUP && groupBy) {
|
||||
await dispatch(fetchGroupedProjects(groupedRequestParams)).unwrap();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error refreshing projects:', error);
|
||||
setErrorMessage('Failed to refresh projects. Please try again.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [trackMixpanelEvent, refetchProjects, viewMode, groupBy, dispatch, groupedRequestParams]);
|
||||
|
||||
// Enhanced empty text with error handling
|
||||
const emptyContent = useMemo(() => {
|
||||
if (errorMessage) {
|
||||
return (
|
||||
<Empty
|
||||
description={
|
||||
<div>
|
||||
<p>{errorMessage}</p>
|
||||
<Button type="primary" onClick={handleRefresh} loading={isLoading}>
|
||||
Retry
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return <Empty description={t('noProjects')} />;
|
||||
}, [errorMessage, handleRefresh, isLoading, t]);
|
||||
|
||||
// Memoize the pagination show total function
|
||||
const paginationShowTotal = useMemo(
|
||||
() => (total: number, range: [number, number]) => `${range[0]}-${range[1]} of ${total} groups`,
|
||||
[]
|
||||
);
|
||||
|
||||
const handleTableChange = useCallback(
|
||||
(
|
||||
newPagination: TablePaginationConfig,
|
||||
|
||||
Reference in New Issue
Block a user