mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
fix date picker
This commit is contained in:
parent
1d8f1b24a9
commit
deb3536cb2
@ -15,7 +15,8 @@
|
||||
"rules": {
|
||||
"indent": ["error", 2, { "SwitchCase": 1 }],
|
||||
"comma-dangle": ["error", { "objects": "always-multiline", "arrays": "always-multiline" }],
|
||||
"no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
|
||||
"no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
|
||||
"no-console": "error"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
|
@ -5,7 +5,7 @@ import ArrowRightDouble from '../icons/ArrowRightDouble';
|
||||
|
||||
const todayTimestamp = new Date().setHours(0, 0, 0, 0).valueOf();
|
||||
|
||||
const Calendar = ({ onChange, calendarRef, close }) => {
|
||||
const Calendar = ({ onChange, calendarRef, close, dateRange }) => {
|
||||
const keyRef = useRef([]);
|
||||
|
||||
const date = new Date();
|
||||
@ -36,7 +36,7 @@ const Calendar = ({ onChange, calendarRef, close }) => {
|
||||
year,
|
||||
month,
|
||||
selectedDay: null,
|
||||
timeRange: { before: null, after: null },
|
||||
timeRange: dateRange,
|
||||
monthDetails: null,
|
||||
});
|
||||
|
||||
|
@ -42,18 +42,21 @@ export default function Events({ path, ...props }) {
|
||||
label: props.label ?? 'all',
|
||||
zone: props.zone ?? 'all',
|
||||
});
|
||||
const [state, setState] = useState({
|
||||
showDownloadMenu: null,
|
||||
showDatePicker: null,
|
||||
showCalendar: null,
|
||||
});
|
||||
const [viewEvent, setViewEvent] = useState();
|
||||
const [downloadEvent, setDownloadEvent] = useState({ id: null, has_clip: false, has_snapshot: false });
|
||||
const [showDownloadMenu, setShowDownloadMenu] = useState();
|
||||
const [showDatePicker, setShowDatePicker] = useState();
|
||||
const [showCalendar, setShowCalendar] = useState();
|
||||
|
||||
const eventsFetcher = (path, params) => {
|
||||
const eventsFetcher = useCallback((path, params) => {
|
||||
params = { ...params, include_thumbnails: 0, limit: API_LIMIT };
|
||||
return axios.get(path, { params }).then((res) => res.data);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const getKey = (index, prevData) => {
|
||||
const getKey = useCallback(
|
||||
(index, prevData) => {
|
||||
if (index > 0) {
|
||||
const lastDate = prevData[prevData.length - 1].start_time;
|
||||
const pagedParams = { ...searchParams, before: lastDate };
|
||||
@ -61,33 +64,32 @@ export default function Events({ path, ...props }) {
|
||||
}
|
||||
|
||||
return ['events', searchParams];
|
||||
};
|
||||
},
|
||||
[searchParams]
|
||||
);
|
||||
|
||||
const { data: eventPages, mutate, size, setSize, isValidating } = useSWRInfinite(getKey, eventsFetcher);
|
||||
|
||||
const { data: config } = useSWR('config');
|
||||
|
||||
const cameras = useMemo(() => Object.keys(config?.cameras || {}), [config]);
|
||||
|
||||
const zones = useMemo(
|
||||
() =>
|
||||
Object.values(config?.cameras || {})
|
||||
const filterValues = useMemo(
|
||||
() => ({
|
||||
cameras: Object.keys(config?.cameras || {}),
|
||||
zones: Object.values(config?.cameras || {})
|
||||
.reduce((memo, camera) => {
|
||||
memo = memo.concat(Object.keys(camera?.zones || {}));
|
||||
return memo;
|
||||
}, [])
|
||||
.filter((value, i, self) => self.indexOf(value) === i),
|
||||
[config]
|
||||
);
|
||||
|
||||
const labels = useMemo(() => {
|
||||
return Object.values(config?.cameras || {})
|
||||
labels: Object.values(config?.cameras || {})
|
||||
.reduce((memo, camera) => {
|
||||
memo = memo.concat(camera?.objects?.track || []);
|
||||
return memo;
|
||||
}, config?.objects?.track || [])
|
||||
.filter((value, i, self) => self.indexOf(value) === i);
|
||||
}, [config]);
|
||||
.filter((value, i, self) => self.indexOf(value) === i),
|
||||
}),
|
||||
[config]
|
||||
);
|
||||
|
||||
const onSave = async (e, eventId, save) => {
|
||||
e.stopPropagation();
|
||||
@ -118,16 +120,15 @@ export default function Events({ path, ...props }) {
|
||||
e.stopPropagation();
|
||||
setDownloadEvent((_prev) => ({ id: event.id, has_clip: event.has_clip, has_snapshot: event.has_snapshot }));
|
||||
downloadButton.current = e.target;
|
||||
setShowDownloadMenu(true);
|
||||
setState({ ...state, showDownloadMenu: true });
|
||||
};
|
||||
|
||||
const handleSelectDateRange = useCallback(
|
||||
(dates) => {
|
||||
console.log(dates);
|
||||
setSearchParams({ ...searchParams, before: dates.before, after: dates.after });
|
||||
setShowDatePicker(false);
|
||||
setState({ ...state, showDatePicker: false });
|
||||
},
|
||||
[searchParams, setSearchParams, setShowDatePicker]
|
||||
[searchParams, setSearchParams, state, setState]
|
||||
);
|
||||
|
||||
const onFilter = useCallback(
|
||||
@ -166,7 +167,7 @@ export default function Events({ path, ...props }) {
|
||||
[size, setSize, isValidating, isDone]
|
||||
);
|
||||
|
||||
if (!eventPages || !config) {
|
||||
if (!config) {
|
||||
return <ActivityIndicator />;
|
||||
}
|
||||
|
||||
@ -180,7 +181,7 @@ export default function Events({ path, ...props }) {
|
||||
onChange={(e) => onFilter('camera', e.target.value)}
|
||||
>
|
||||
<option value="all">all</option>
|
||||
{cameras.map((item) => (
|
||||
{filterValues.cameras.map((item) => (
|
||||
<option key={item} value={item}>
|
||||
{item}
|
||||
</option>
|
||||
@ -192,7 +193,7 @@ export default function Events({ path, ...props }) {
|
||||
onChange={(e) => onFilter('label', e.target.value)}
|
||||
>
|
||||
<option value="all">all</option>
|
||||
{labels.map((item) => (
|
||||
{filterValues.labels.map((item) => (
|
||||
<option key={item} value={item}>
|
||||
{item}
|
||||
</option>
|
||||
@ -204,18 +205,21 @@ export default function Events({ path, ...props }) {
|
||||
onChange={(e) => onFilter('zone', e.target.value)}
|
||||
>
|
||||
<option value="all">all</option>
|
||||
{zones.map((item) => (
|
||||
{filterValues.zones.map((item) => (
|
||||
<option key={item} value={item}>
|
||||
{item}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<div ref={datePicker} className="ml-auto">
|
||||
<CalendarIcon className="h-8 w-8 cursor-pointer" onClick={() => setShowDatePicker(true)} />
|
||||
<CalendarIcon
|
||||
className="h-8 w-8 cursor-pointer"
|
||||
onClick={() => setState({ ...state, showDatePicker: true })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{showDownloadMenu && (
|
||||
<Menu onDismiss={() => setShowDownloadMenu(false)} relativeTo={downloadButton}>
|
||||
{state.showDownloadMenu && (
|
||||
<Menu onDismiss={() => setState({ ...state, showDownloadMenu: false })} relativeTo={downloadButton}>
|
||||
{downloadEvent.has_snapshot && (
|
||||
<MenuItem
|
||||
icon={Snapshot}
|
||||
@ -236,8 +240,12 @@ export default function Events({ path, ...props }) {
|
||||
)}
|
||||
</Menu>
|
||||
)}
|
||||
{showDatePicker && (
|
||||
<Menu className="rounded-t-none" onDismiss={() => setShowDatePicker(false)} relativeTo={datePicker}>
|
||||
{state.showDatePicker && (
|
||||
<Menu
|
||||
className="rounded-t-none"
|
||||
onDismiss={() => setState({ ...state, setShowDatePicker: false })}
|
||||
relativeTo={datePicker}
|
||||
>
|
||||
<MenuItem label="All" value={{ before: null, after: null }} onSelect={handleSelectDateRange} />
|
||||
<MenuItem label="Today" value={{ before: null, after: daysAgo(0) }} onSelect={handleSelectDateRange} />
|
||||
<MenuItem
|
||||
@ -256,19 +264,27 @@ export default function Events({ path, ...props }) {
|
||||
label="Custom Range"
|
||||
value="custom"
|
||||
onSelect={() => {
|
||||
setShowCalendar(true);
|
||||
setShowDatePicker(false);
|
||||
setState({ ...state, showCalendar: true, showDatePicker: false });
|
||||
}}
|
||||
/>
|
||||
</Menu>
|
||||
)}
|
||||
{showCalendar && (
|
||||
<Menu className="rounded-t-none" onDismiss={() => setShowCalendar(false)} relativeTo={datePicker}>
|
||||
<Calendar onChange={handleSelectDateRange} close={() => setShowCalendar(false)} />
|
||||
{state.showCalendar && (
|
||||
<Menu
|
||||
className="rounded-t-none"
|
||||
onDismiss={() => setState({ ...state, showCalendar: false })}
|
||||
relativeTo={datePicker}
|
||||
>
|
||||
<Calendar
|
||||
onChange={handleSelectDateRange}
|
||||
dateRange={{ before: searchParams.before * 1000 || null, after: searchParams.after * 1000 || null }}
|
||||
close={() => setState({ ...state, showCalendar: false })}
|
||||
/>
|
||||
</Menu>
|
||||
)}
|
||||
<div className="space-y-2">
|
||||
{eventPages.map((page, i) => {
|
||||
{eventPages ? (
|
||||
eventPages.map((page, i) => {
|
||||
const lastPage = eventPages.length === i + 1;
|
||||
return page.map((event, j) => {
|
||||
const lastEvent = lastPage && page.length === j + 1;
|
||||
@ -368,7 +384,10 @@ export default function Events({ path, ...props }) {
|
||||
</Fragment>
|
||||
);
|
||||
});
|
||||
})}
|
||||
})
|
||||
) : (
|
||||
<ActivityIndicator />
|
||||
)}
|
||||
</div>
|
||||
<div>{isDone ? null : <ActivityIndicator />}</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user