wip: enforce max chart points when selecting unit

This commit is contained in:
Caio Carvalho 2024-11-21 01:20:35 -03:00
parent 0948cb40c0
commit d7ade2f80f
5 changed files with 39 additions and 16 deletions

View file

@ -1,13 +1,14 @@
import { useMessages } from 'components/hooks'; import { useDateRange, useMessages } from 'components/hooks';
import useTimeUnit from 'components/hooks/useTimeUnit'; import useTimeUnit from 'components/hooks/useTimeUnit';
import { Button, Dropdown, Flexbox, Item } from 'react-basics'; import { Button, Dropdown, Flexbox, Item } from 'react-basics';
import styles from './TimeUnitSettings.module.css'; import styles from './TimeUnitSettings.module.css';
export function TimeUnitSettings() { export function TimeUnitSettings() {
const { formatMessage, labels } = useMessages(); const { formatMessage, labels } = useMessages();
const { timeUnit, timeUnitOptions, updateTimeUnit } = useTimeUnit(); const { dateRange } = useDateRange();
const { timeUnit, timeUnitOptions, updateTimeUnit } = useTimeUnit(dateRange);
const handleReset = () => updateTimeUnit('hour'); const handleReset = () => updateTimeUnit('day');
return ( return (
<Flexbox gap={10}> <Flexbox gap={10}>

View file

@ -1,28 +1,46 @@
import { DEFAULT_TIME_UNIT, TIME_UNIT_CONFIG } from 'lib/constants'; import { DEFAULT_TIME_UNIT, MAX_CHART_POINTS, TIME_UNIT_CONFIG, UNIT_TYPES } from 'lib/constants';
import { TimeUnit } from 'lib/types'; import { getDateLength } from 'lib/date';
import { DateRange, TimeUnit } from 'lib/types';
import { getItem, setItem } from 'next-basics'; import { getItem, setItem } from 'next-basics';
import { useState } from 'react'; import { useState } from 'react';
import useStore, { setTimeUnit } from 'store/app'; import useStore, { setTimeUnit } from 'store/app';
const selector = (state: { timeUnit: string }) => state.timeUnit; const selector = (state: { timeUnit: string }) => state.timeUnit;
export function useTimeUnit() { export function useTimeUnit(dateRange?: DateRange) {
const storeTimeUnit = useStore(selector) || getItem(TIME_UNIT_CONFIG) || DEFAULT_TIME_UNIT; const storeTimeUnit = useStore(selector) || getItem(TIME_UNIT_CONFIG) || DEFAULT_TIME_UNIT;
const [tempTimeUnit, setTempTimeUnit] = useState<TimeUnit>(storeTimeUnit); const validTimeUnits = getValidTimeUnits(dateRange);
const timeUnitOptions = ['hour', 'day', 'week', 'month', 'year']; const [tempTimeUnit, setTempTimeUnit] = useState<TimeUnit>(() => {
return validTimeUnits.includes(storeTimeUnit) ? storeTimeUnit : validTimeUnits[0];
});
function getValidTimeUnits(dateRange: DateRange) {
if (!dateRange?.startDate || !dateRange?.endDate) {
return UNIT_TYPES;
}
return UNIT_TYPES.filter(unit => {
const points = getDateLength(dateRange.startDate, dateRange.endDate, unit);
return points <= MAX_CHART_POINTS;
});
}
function updateTimeUnit(value: TimeUnit) { function updateTimeUnit(value: TimeUnit) {
setTempTimeUnit(value); if (validTimeUnits.includes(value)) {
setTempTimeUnit(value);
}
} }
function saveTimeUnit() { function saveTimeUnit() {
setTimeUnit(tempTimeUnit); if (validTimeUnits.includes(tempTimeUnit)) {
setItem(TIME_UNIT_CONFIG, tempTimeUnit); setTimeUnit(tempTimeUnit);
setItem(TIME_UNIT_CONFIG, tempTimeUnit);
}
} }
return { return {
timeUnit: tempTimeUnit, timeUnit: tempTimeUnit,
timeUnitOptions, timeUnitOptions: validTimeUnits,
updateTimeUnit, updateTimeUnit,
saveTimeUnit, saveTimeUnit,
}; };

View file

@ -1,18 +1,20 @@
import TimeUnitSettings from 'app/(main)/profile/TimeUnitSettings'; import TimeUnitSettings from 'app/(main)/profile/TimeUnitSettings';
import { useMessages } from 'components/hooks'; import { useDateRange, useMessages } from 'components/hooks';
import useTimeUnit from 'components/hooks/useTimeUnit'; import useTimeUnit from 'components/hooks/useTimeUnit';
import { Button, Form, FormRow, Modal } from 'react-basics'; import { Button, Form, FormRow, Modal } from 'react-basics';
import styles from './WebsiteChartSettings.module.css'; import styles from './WebsiteChartSettings.module.css';
export interface WebsiteChartSettingsProps { export interface WebsiteChartSettingsProps {
websiteId: string;
isOpened?: boolean; isOpened?: boolean;
onClose: () => void; onClose: () => void;
onChange?: (value: string) => void; onChange?: (value: string) => void;
} }
export function WebsiteChartSettings({ onClose }: WebsiteChartSettingsProps) { export function WebsiteChartSettings({ websiteId, onClose }: WebsiteChartSettingsProps) {
const { formatMessage, labels } = useMessages(); const { formatMessage, labels } = useMessages();
const { saveTimeUnit } = useTimeUnit(); const { dateRange } = useDateRange(websiteId);
const { saveTimeUnit } = useTimeUnit(dateRange);
const handleSave = () => { const handleSave = () => {
saveTimeUnit(); saveTimeUnit();

View file

@ -62,6 +62,7 @@ export function WebsiteDateFilter({
</Button> </Button>
{showChartParams && ( {showChartParams && (
<WebsiteChartSettings <WebsiteChartSettings
websiteId={websiteId}
isOpened={showChartParams} isOpened={showChartParams}
onClose={() => setShowChartParams(false)} onClose={() => setShowChartParams(false)}
onChange={handleChange} onChange={handleChange}

View file

@ -18,7 +18,7 @@ export const DEFAULT_LOCALE = process.env.defaultLocale || 'en-US';
export const DEFAULT_THEME = 'light'; export const DEFAULT_THEME = 'light';
export const DEFAULT_ANIMATION_DURATION = 300; export const DEFAULT_ANIMATION_DURATION = 300;
export const DEFAULT_DATE_RANGE = '24hour'; export const DEFAULT_DATE_RANGE = '24hour';
export const DEFAULT_TIME_UNIT = '1hour'; export const DEFAULT_TIME_UNIT = 'day';
export const DEFAULT_WEBSITE_LIMIT = 10; export const DEFAULT_WEBSITE_LIMIT = 10;
export const DEFAULT_RESET_DATE = '2000-01-01'; export const DEFAULT_RESET_DATE = '2000-01-01';
export const DEFAULT_PAGE_SIZE = 10; export const DEFAULT_PAGE_SIZE = 10;
@ -26,6 +26,7 @@ export const DEFAULT_DATE_COMPARE = 'prev';
export const REALTIME_RANGE = 30; export const REALTIME_RANGE = 30;
export const REALTIME_INTERVAL = 10000; export const REALTIME_INTERVAL = 10000;
export const MAX_CHART_POINTS = 720;
export const FILTER_COMBINED = 'filter-combined'; export const FILTER_COMBINED = 'filter-combined';
export const FILTER_RAW = 'filter-raw'; export const FILTER_RAW = 'filter-raw';