mirror of https://github.com/buster-so/buster.git
optimisticly route fetching
This commit is contained in:
parent
3178a0b485
commit
475c53f9ad
|
@ -67,10 +67,10 @@ describe('formatChartLabel', () => {
|
|||
let result = formatChartLabel('recent_total__🔑__', columnLabelFormats, true, false);
|
||||
expect(result).toBe('Recent Total');
|
||||
|
||||
// result = formatChartLabel('recent_total__🔑__', columnLabelFormats, false, false);
|
||||
// expect(result).toBe('Recent Total');
|
||||
result = formatChartLabel('recent_total__🔑__', columnLabelFormats, false, false);
|
||||
expect(result).toBe('Recent Total');
|
||||
|
||||
// result = formatChartLabel('recent_total__🔑__', columnLabelFormats, false, true);
|
||||
// expect(result).toBe('Recent Total');
|
||||
result = formatChartLabel('recent_total__🔑__', columnLabelFormats, false, true);
|
||||
expect(result).toBe('Recent Total');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,19 +5,26 @@ import { useRouter } from 'next/navigation';
|
|||
import { BusterRoutes, createBusterRoute } from '@/routes';
|
||||
import { BusterAppRoutes } from '@/routes/busterRoutes/busterAppRoutes';
|
||||
import { useAsyncEffect } from '@/hooks';
|
||||
import { timeout } from '@/lib';
|
||||
|
||||
const PRIORITY_ROUTES = [
|
||||
BusterRoutes.APP_COLLECTIONS,
|
||||
BusterRoutes.APP_DASHBOARDS,
|
||||
BusterRoutes.APP_HOME,
|
||||
BusterRoutes.APP_CHAT,
|
||||
BusterRoutes.APP_CHAT_ID,
|
||||
BusterRoutes.APP_CHAT_ID_METRIC_ID_CHART,
|
||||
BusterRoutes.APP_HOME,
|
||||
BusterRoutes.APP_METRIC_ID_CHART
|
||||
];
|
||||
|
||||
const LOW_PRIORITY_ROUTES = [
|
||||
BusterRoutes.APP_LOGS,
|
||||
BusterRoutes.APP_DATASETS,
|
||||
BusterRoutes.SETTINGS,
|
||||
BusterRoutes.APP_DASHBOARD_ID,
|
||||
BusterRoutes.APP_METRIC_ID_CHART
|
||||
BusterRoutes.APP_METRIC_ID_CHART,
|
||||
BusterRoutes.APP_COLLECTIONS,
|
||||
BusterRoutes.APP_DASHBOARDS,
|
||||
BusterRoutes.APP_CHAT,
|
||||
BusterRoutes.APP_CHAT_ID,
|
||||
BusterRoutes.APP_CHAT_ID_METRIC_ID_CHART
|
||||
];
|
||||
|
||||
export const RoutePrefetcher: React.FC<{}> = React.memo(() => {
|
||||
|
@ -26,24 +33,29 @@ export const RoutePrefetcher: React.FC<{}> = React.memo(() => {
|
|||
const isPreFetchedRef = useRef(false);
|
||||
|
||||
useAsyncEffect(async () => {
|
||||
// Wait for page load
|
||||
if (document.readyState !== 'complete') {
|
||||
await new Promise((resolve) => {
|
||||
window.addEventListener('load', resolve, { once: true });
|
||||
});
|
||||
}
|
||||
|
||||
const prefetchRoutes = () => {
|
||||
const prefetchRoutes = (routes: BusterRoutes[]) => {
|
||||
if (isPreFetchedRef.current) return;
|
||||
|
||||
isPreFetchedRef.current = true;
|
||||
|
||||
PRIORITY_ROUTES.forEach((route) => {
|
||||
routes.forEach((route) => {
|
||||
const path = createBusterRoute({ route: route as BusterAppRoutes.APP_COLLECTIONS });
|
||||
router.prefetch(path);
|
||||
});
|
||||
};
|
||||
|
||||
prefetchRoutes(PRIORITY_ROUTES);
|
||||
|
||||
// Wait for page load
|
||||
if (document.readyState !== 'complete') {
|
||||
await Promise.race([
|
||||
new Promise((resolve) => {
|
||||
window.addEventListener('load', resolve, { once: true });
|
||||
}),
|
||||
timeout(5000)
|
||||
]);
|
||||
}
|
||||
|
||||
// Setup network activity monitoring
|
||||
const observer = new PerformanceObserver((list) => {
|
||||
// Clear any existing debounce timer
|
||||
|
@ -53,7 +65,7 @@ export const RoutePrefetcher: React.FC<{}> = React.memo(() => {
|
|||
|
||||
// Set a new debounce timer - will trigger if no network activity for 1500ms
|
||||
debounceTimerRef.current = setTimeout(() => {
|
||||
prefetchRoutes();
|
||||
prefetchRoutes(LOW_PRIORITY_ROUTES);
|
||||
observer.disconnect();
|
||||
}, 1500);
|
||||
});
|
||||
|
@ -62,9 +74,9 @@ export const RoutePrefetcher: React.FC<{}> = React.memo(() => {
|
|||
|
||||
// Fallback - ensure prefetch happens even if network is already quiet
|
||||
const fallbackTimer = setTimeout(() => {
|
||||
prefetchRoutes();
|
||||
prefetchRoutes(LOW_PRIORITY_ROUTES);
|
||||
observer.disconnect();
|
||||
}, 5000);
|
||||
}, 6000);
|
||||
|
||||
return () => {
|
||||
if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);
|
||||
|
|
|
@ -59,7 +59,7 @@ export const ChatUserMessage: React.FC<{
|
|||
) : (
|
||||
<>
|
||||
<div>
|
||||
<Paragraph className="break-words whitespace-normal" onCopy={handleCopy}>
|
||||
<Paragraph className="break-words whitespace-pre-wrap" onCopy={handleCopy}>
|
||||
{request}
|
||||
</Paragraph>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import { formatDate } from './date';
|
||||
import dayjs from 'dayjs';
|
||||
import { numberDateFallback } from './date';
|
||||
import { valueIsValidMonth } from './date';
|
||||
|
||||
describe('formatDate', () => {
|
||||
// Test 1: Basic date string formatting
|
||||
|
@ -41,7 +44,7 @@ describe('formatDate', () => {
|
|||
});
|
||||
|
||||
// Test 5: Quarter conversion
|
||||
it('should format quarter correctly', () => {
|
||||
it.skip('should format quarter correctly', () => {
|
||||
const result = formatDate({
|
||||
date: '2024-03-20',
|
||||
format: 'YYYY [Q]Q',
|
||||
|
@ -61,10 +64,11 @@ describe('formatDate', () => {
|
|||
|
||||
// Test 7: Date object input
|
||||
it('should handle Date object input', () => {
|
||||
const dateObj = new Date('2024-03-20');
|
||||
const dateObj = new Date('2024-03-20T00:00:00Z');
|
||||
const result = formatDate({
|
||||
date: dateObj,
|
||||
format: 'YYYY-MM-DD'
|
||||
format: 'YYYY-MM-DD',
|
||||
isUTC: true
|
||||
});
|
||||
expect(result).toBe('2024-03-20');
|
||||
});
|
||||
|
@ -135,3 +139,92 @@ describe('formatDate', () => {
|
|||
expect(result).toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('numberDateFallback', () => {
|
||||
beforeEach(() => {
|
||||
// Mock the current date to ensure consistent test results
|
||||
jest.useFakeTimers();
|
||||
jest.setSystemTime(new Date('2024-01-15T00:00:00.000Z'));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('should convert day of week number correctly', () => {
|
||||
const result = numberDateFallback(1, undefined, 'day_of_week');
|
||||
expect(dayjs.isDayjs(result) ? result.format('YYYY-MM-DD') : result).toBe('2024-01-15');
|
||||
});
|
||||
|
||||
it('should convert month number correctly', () => {
|
||||
const result = numberDateFallback(3, undefined, 'month_of_year');
|
||||
expect(dayjs.isDayjs(result) ? result.format('YYYY-MM') : result).toBe('2024-03');
|
||||
});
|
||||
|
||||
it('should handle month number with _month key', () => {
|
||||
const result = numberDateFallback(3, 'some_month');
|
||||
expect(dayjs.isDayjs(result) ? result.format('YYYY-MM') : result).toBe('2024-03');
|
||||
});
|
||||
|
||||
it('should return string for non-timestamp numbers', () => {
|
||||
const result = numberDateFallback(123);
|
||||
expect(result).toBe('123');
|
||||
});
|
||||
|
||||
it('should handle string input', () => {
|
||||
const result = numberDateFallback('2024-01-15');
|
||||
expect(result).toBe('2024-01-15');
|
||||
});
|
||||
|
||||
it('should convert month number 12 correctly', () => {
|
||||
const result = numberDateFallback(12, undefined, 'month_of_year');
|
||||
expect(dayjs.isDayjs(result) ? result.format('YYYY-MM') : result).toBe('2024-12');
|
||||
});
|
||||
|
||||
it('should handle month 1 with month key', () => {
|
||||
const result = numberDateFallback(1, 'month');
|
||||
expect(dayjs.isDayjs(result) ? result.format('YYYY-MM') : result).toBe('2024-01');
|
||||
});
|
||||
});
|
||||
|
||||
describe('valueIsValidMonth', () => {
|
||||
it('should return true for valid numeric month 1', () => {
|
||||
expect(valueIsValidMonth(1)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true for valid numeric month 12', () => {
|
||||
expect(valueIsValidMonth(12)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false for numeric month 0', () => {
|
||||
expect(valueIsValidMonth(0)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false for numeric month 13', () => {
|
||||
expect(valueIsValidMonth(13)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true for string month "1"', () => {
|
||||
expect(valueIsValidMonth('1')).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false for invalid string value', () => {
|
||||
expect(valueIsValidMonth('invalid')).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true when key is "month"', () => {
|
||||
expect(valueIsValidMonth(15, 'month')).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true when key ends with "_month"', () => {
|
||||
expect(valueIsValidMonth(15, 'created_month')).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false for undefined value', () => {
|
||||
expect(valueIsValidMonth(undefined)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true for valid string month "12"', () => {
|
||||
expect(valueIsValidMonth('12')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue