Require apply for custom date range
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m34s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m34s
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useRef } from 'react';
|
import React, { useRef, useState } from 'react';
|
||||||
import { Calendar, RefreshCw, ChevronDown } from 'lucide-react';
|
import { Calendar, RefreshCw, ChevronDown } from 'lucide-react';
|
||||||
import type { DateRange } from '../types';
|
import type { DateRange } from '../types';
|
||||||
import { endOfLocalDay, formatDateParam, parseLocalDateInput, rangeForDay, rangeForLastDays, rangeForPreviousDay, startOfLocalDay } from '../dateRanges';
|
import { endOfLocalDay, formatDateParam, parseLocalDateInput, rangeForDay, rangeForLastDays, rangeForPreviousDay, startOfLocalDay } from '../dateRanges';
|
||||||
@@ -32,10 +32,18 @@ const REFRESH_OPTIONS = [
|
|||||||
{ label: '5m', value: 300000 },
|
{ label: '5m', value: 300000 },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const getRangeKey = (range: DateRange) => `${formatDateParam(range.start)}:${formatDateParam(range.end)}`;
|
||||||
|
|
||||||
const DateRangePicker: React.FC<DateRangePickerProps> = ({ dateRange, onChange, refreshInterval, setRefreshInterval, onManualRefresh }) => {
|
const DateRangePicker: React.FC<DateRangePickerProps> = ({ dateRange, onChange, refreshInterval, setRefreshInterval, onManualRefresh }) => {
|
||||||
const [isPresetOpen, setIsPresetOpen] = useState(false);
|
const [isPresetOpen, setIsPresetOpen] = useState(false);
|
||||||
|
const [customDraft, setCustomDraft] = useState(() => ({
|
||||||
|
appliedKey: getRangeKey(dateRange),
|
||||||
|
range: dateRange
|
||||||
|
}));
|
||||||
const startRef = useRef<HTMLInputElement>(null);
|
const startRef = useRef<HTMLInputElement>(null);
|
||||||
const endRef = useRef<HTMLInputElement>(null);
|
const endRef = useRef<HTMLInputElement>(null);
|
||||||
|
const appliedRangeKey = getRangeKey(dateRange);
|
||||||
|
const draftRange = customDraft.appliedKey === appliedRangeKey ? customDraft.range : dateRange;
|
||||||
|
|
||||||
const formatDisplayDate = (date: Date) => {
|
const formatDisplayDate = (date: Date) => {
|
||||||
return date.toLocaleDateString('pt-BR', { day: '2-digit', month: '2-digit', year: 'numeric' });
|
return date.toLocaleDateString('pt-BR', { day: '2-digit', month: '2-digit', year: 'numeric' });
|
||||||
@@ -49,8 +57,8 @@ const DateRangePicker: React.FC<DateRangePickerProps> = ({ dateRange, onChange,
|
|||||||
const newStart = parseLocalDateInput(e.target.value);
|
const newStart = parseLocalDateInput(e.target.value);
|
||||||
if (newStart && !isNaN(newStart.getTime())) {
|
if (newStart && !isNaN(newStart.getTime())) {
|
||||||
const start = startOfLocalDay(newStart);
|
const start = startOfLocalDay(newStart);
|
||||||
const end = dateRange.end < start ? endOfLocalDay(start) : dateRange.end;
|
const end = draftRange.end < start ? endOfLocalDay(start) : draftRange.end;
|
||||||
onChange({ start, end });
|
setCustomDraft({ appliedKey: appliedRangeKey, range: { start, end } });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -58,11 +66,19 @@ const DateRangePicker: React.FC<DateRangePickerProps> = ({ dateRange, onChange,
|
|||||||
const newEnd = parseLocalDateInput(e.target.value);
|
const newEnd = parseLocalDateInput(e.target.value);
|
||||||
if (newEnd && !isNaN(newEnd.getTime())) {
|
if (newEnd && !isNaN(newEnd.getTime())) {
|
||||||
const end = endOfLocalDay(newEnd);
|
const end = endOfLocalDay(newEnd);
|
||||||
const start = dateRange.start > end ? startOfLocalDay(end) : dateRange.start;
|
const start = draftRange.start > end ? startOfLocalDay(end) : draftRange.start;
|
||||||
onChange({ start, end });
|
setCustomDraft({ appliedKey: appliedRangeKey, range: { start, end } });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const draftRangeKey = getRangeKey(draftRange);
|
||||||
|
const isDraftApplied = draftRangeKey === appliedRangeKey;
|
||||||
|
|
||||||
|
const handleApplyCustomRange = () => {
|
||||||
|
onChange(draftRange);
|
||||||
|
setIsPresetOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
const openPicker = (ref: React.RefObject<HTMLInputElement | null>) => {
|
const openPicker = (ref: React.RefObject<HTMLInputElement | null>) => {
|
||||||
if (ref.current) {
|
if (ref.current) {
|
||||||
try {
|
try {
|
||||||
@@ -103,11 +119,11 @@ const DateRangePicker: React.FC<DateRangePickerProps> = ({ dateRange, onChange,
|
|||||||
className="relative bg-dark-input border border-dark-border text-dark-text text-xs rounded-lg px-2 py-1 focus-within:border-brand-primary w-full cursor-pointer overflow-hidden flex items-center h-6"
|
className="relative bg-dark-input border border-dark-border text-dark-text text-xs rounded-lg px-2 py-1 focus-within:border-brand-primary w-full cursor-pointer overflow-hidden flex items-center h-6"
|
||||||
onClick={() => openPicker(startRef)}
|
onClick={() => openPicker(startRef)}
|
||||||
>
|
>
|
||||||
<span className="w-full text-center">{formatDisplayDate(dateRange.start)}</span>
|
<span className="w-full text-center">{formatDisplayDate(draftRange.start)}</span>
|
||||||
<input
|
<input
|
||||||
ref={startRef}
|
ref={startRef}
|
||||||
type="date"
|
type="date"
|
||||||
value={formatDateForInput(dateRange.start)}
|
value={formatDateForInput(draftRange.start)}
|
||||||
onChange={handleStartChange}
|
onChange={handleStartChange}
|
||||||
className="absolute inset-0 opacity-0 cursor-pointer"
|
className="absolute inset-0 opacity-0 cursor-pointer"
|
||||||
/>
|
/>
|
||||||
@@ -119,16 +135,24 @@ const DateRangePicker: React.FC<DateRangePickerProps> = ({ dateRange, onChange,
|
|||||||
className="relative bg-dark-input border border-dark-border text-dark-text text-xs rounded-lg px-2 py-1 focus-within:border-brand-primary w-full cursor-pointer overflow-hidden flex items-center h-6"
|
className="relative bg-dark-input border border-dark-border text-dark-text text-xs rounded-lg px-2 py-1 focus-within:border-brand-primary w-full cursor-pointer overflow-hidden flex items-center h-6"
|
||||||
onClick={() => openPicker(endRef)}
|
onClick={() => openPicker(endRef)}
|
||||||
>
|
>
|
||||||
<span className="w-full text-center">{formatDisplayDate(dateRange.end)}</span>
|
<span className="w-full text-center">{formatDisplayDate(draftRange.end)}</span>
|
||||||
<input
|
<input
|
||||||
ref={endRef}
|
ref={endRef}
|
||||||
type="date"
|
type="date"
|
||||||
value={formatDateForInput(dateRange.end)}
|
value={formatDateForInput(draftRange.end)}
|
||||||
onChange={handleEndChange}
|
onChange={handleEndChange}
|
||||||
className="absolute inset-0 opacity-0 cursor-pointer"
|
className="absolute inset-0 opacity-0 cursor-pointer"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleApplyCustomRange}
|
||||||
|
disabled={isDraftApplied}
|
||||||
|
className="mt-1 inline-flex h-8 w-full items-center justify-center rounded-lg bg-brand-primary px-3 text-xs font-bold text-white transition-colors hover:bg-brand-primary/90 disabled:cursor-not-allowed disabled:bg-dark-input disabled:text-dark-muted cursor-pointer"
|
||||||
|
>
|
||||||
|
Aplicar
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span className="px-4 text-xs font-bold text-dark-muted uppercase tracking-widest mb-1 block">Atalhos</span>
|
<span className="px-4 text-xs font-bold text-dark-muted uppercase tracking-widest mb-1 block">Atalhos</span>
|
||||||
@@ -136,7 +160,9 @@ const DateRangePicker: React.FC<DateRangePickerProps> = ({ dateRange, onChange,
|
|||||||
<button
|
<button
|
||||||
key={preset.label}
|
key={preset.label}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onChange(preset.getRange());
|
const nextRange = preset.getRange();
|
||||||
|
setCustomDraft({ appliedKey: getRangeKey(nextRange), range: nextRange });
|
||||||
|
onChange(nextRange);
|
||||||
setIsPresetOpen(false);
|
setIsPresetOpen(false);
|
||||||
}}
|
}}
|
||||||
className="w-full text-left px-4 py-2 text-sm text-dark-muted hover:text-dark-text hover:bg-dark-input transition-colors cursor-pointer"
|
className="w-full text-left px-4 py-2 text-sm text-dark-muted hover:text-dark-text hover:bg-dark-input transition-colors cursor-pointer"
|
||||||
|
|||||||
Reference in New Issue
Block a user