feat: allow future dates for Google Calendar and Luma connectors

- Updated date handling in indexing functions to permit future dates for Google Calendar and Luma connectors.
- Enhanced UI components to support future date selection, including a new button for selecting the next 30 days.
- Adjusted documentation and descriptions to clarify date range options for users.
This commit is contained in:
Anish Sarkar 2026-01-09 13:20:12 +05:30
parent 1b4ec2daa7
commit 4aeb05e2e5
7 changed files with 80 additions and 39 deletions

View file

@ -541,7 +541,7 @@ async def index_connector_content(
), ),
end_date: str = Query( end_date: str = Query(
None, None,
description="End date for indexing (YYYY-MM-DD format). If not provided, uses today's date", description="End date for indexing (YYYY-MM-DD format). If not provided, uses today's date. For calendar connectors (Google Calendar, Luma), future dates can be selected to index upcoming events.",
), ),
drive_items: GoogleDriveIndexRequest | None = Body( drive_items: GoogleDriveIndexRequest | None = Body(
None, None,
@ -614,6 +614,18 @@ async def index_connector_content(
else: else:
indexing_from = start_date indexing_from = start_date
# For calendar connectors, default to today but allow future dates if explicitly provided
if connector.connector_type in [
SearchSourceConnectorType.GOOGLE_CALENDAR_CONNECTOR,
SearchSourceConnectorType.LUMA_CONNECTOR,
]:
# Default to today if no end_date provided (users can manually select future dates)
if end_date is None:
indexing_to = today_str
else:
indexing_to = end_date
else:
# For non-calendar connectors, cap at today
indexing_to = end_date if end_date else today_str indexing_to = end_date if end_date else today_str
if connector.connector_type == SearchSourceConnectorType.SLACK_CONNECTOR: if connector.connector_type == SearchSourceConnectorType.SLACK_CONNECTOR:

View file

@ -45,8 +45,9 @@ async def index_google_calendar_events(
connector_id: ID of the Google Calendar connector connector_id: ID of the Google Calendar connector
search_space_id: ID of the search space to store documents in search_space_id: ID of the search space to store documents in
user_id: User ID user_id: User ID
start_date: Start date for indexing (YYYY-MM-DD format) start_date: Start date for indexing (YYYY-MM-DD format). Can be in the past or future.
end_date: End date for indexing (YYYY-MM-DD format) end_date: End date for indexing (YYYY-MM-DD format). Can be in the future to index upcoming events.
Defaults to today if not provided.
update_last_indexed: Whether to update the last_indexed_at timestamp (default: True) update_last_indexed: Whether to update the last_indexed_at timestamp (default: True)
Returns: Returns:
@ -165,8 +166,10 @@ async def index_google_calendar_events(
end_date = None end_date = None
# Calculate date range # Calculate date range
# For calendar connectors, allow future dates to index upcoming events
if start_date is None or end_date is None: if start_date is None or end_date is None:
# Fall back to calculating dates based on last_indexed_at # Fall back to calculating dates based on last_indexed_at
# Default to today (users can manually select future dates if needed)
calculated_end_date = datetime.now() calculated_end_date = datetime.now()
# Use last_indexed_at as start date if available, otherwise use 30 days ago # Use last_indexed_at as start date if available, otherwise use 30 days ago
@ -178,19 +181,13 @@ async def index_google_calendar_events(
else connector.last_indexed_at else connector.last_indexed_at
) )
# Check if last_indexed_at is in the future or after end_date # Allow future dates - use last_indexed_at as start date
if last_indexed_naive > calculated_end_date:
logger.warning(
f"Last indexed date ({last_indexed_naive.strftime('%Y-%m-%d')}) is in the future. Using 30 days ago instead."
)
calculated_start_date = calculated_end_date - timedelta(days=30)
else:
calculated_start_date = last_indexed_naive calculated_start_date = last_indexed_naive
logger.info( logger.info(
f"Using last_indexed_at ({calculated_start_date.strftime('%Y-%m-%d')}) as start date" f"Using last_indexed_at ({calculated_start_date.strftime('%Y-%m-%d')}) as start date"
) )
else: else:
calculated_start_date = calculated_end_date - timedelta( calculated_start_date = datetime.now() - timedelta(
days=30 days=30
) # Use 30 days as default for calendar events ) # Use 30 days as default for calendar events
logger.info( logger.info(
@ -205,7 +202,7 @@ async def index_google_calendar_events(
end_date if end_date else calculated_end_date.strftime("%Y-%m-%d") end_date if end_date else calculated_end_date.strftime("%Y-%m-%d")
) )
else: else:
# Use provided dates # Use provided dates (including future dates)
start_date_str = start_date start_date_str = start_date
end_date_str = end_date end_date_str = end_date

View file

@ -45,8 +45,9 @@ async def index_luma_events(
connector_id: ID of the Luma connector connector_id: ID of the Luma connector
search_space_id: ID of the search space to store documents in search_space_id: ID of the search space to store documents in
user_id: User ID user_id: User ID
start_date: Start date for indexing (YYYY-MM-DD format) start_date: Start date for indexing (YYYY-MM-DD format). Can be in the past or future.
end_date: End date for indexing (YYYY-MM-DD format) end_date: End date for indexing (YYYY-MM-DD format). Can be in the future to index upcoming events.
Defaults to today if not provided.
update_last_indexed: Whether to update the last_indexed_at timestamp (default: True) update_last_indexed: Whether to update the last_indexed_at timestamp (default: True)
Returns: Returns:
@ -116,8 +117,10 @@ async def index_luma_events(
luma_client = LumaConnector(api_key=api_key) luma_client = LumaConnector(api_key=api_key)
# Calculate date range # Calculate date range
# For calendar connectors, allow future dates to index upcoming events
if start_date is None or end_date is None: if start_date is None or end_date is None:
# Fall back to calculating dates based on last_indexed_at # Fall back to calculating dates based on last_indexed_at
# Default to today (users can manually select future dates if needed)
calculated_end_date = datetime.now() calculated_end_date = datetime.now()
# Use last_indexed_at as start date if available, otherwise use 30 days ago # Use last_indexed_at as start date if available, otherwise use 30 days ago
@ -129,19 +132,13 @@ async def index_luma_events(
else connector.last_indexed_at else connector.last_indexed_at
) )
# Check if last_indexed_at is in the future or after end_date # Allow future dates - use last_indexed_at as start date
if last_indexed_naive > calculated_end_date:
logger.warning(
f"Last indexed date ({last_indexed_naive.strftime('%Y-%m-%d')}) is in the future. Using 30 days ago instead."
)
calculated_start_date = calculated_end_date - timedelta(days=30)
else:
calculated_start_date = last_indexed_naive calculated_start_date = last_indexed_naive
logger.info( logger.info(
f"Using last_indexed_at ({calculated_start_date.strftime('%Y-%m-%d')}) as start date" f"Using last_indexed_at ({calculated_start_date.strftime('%Y-%m-%d')}) as start date"
) )
else: else:
calculated_start_date = calculated_end_date - timedelta(days=30) calculated_start_date = datetime.now() - timedelta(days=30)
logger.info( logger.info(
f"No last_indexed_at found, using {calculated_start_date.strftime('%Y-%m-%d')} (30 days ago) as start date" f"No last_indexed_at found, using {calculated_start_date.strftime('%Y-%m-%d')} (30 days ago) as start date"
) )
@ -154,7 +151,7 @@ async def index_luma_events(
end_date if end_date else calculated_end_date.strftime("%Y-%m-%d") end_date if end_date else calculated_end_date.strftime("%Y-%m-%d")
) )
else: else:
# Use provided dates # Use provided dates (including future dates)
start_date_str = start_date start_date_str = start_date
end_date_str = end_date end_date_str = end_date

View file

@ -1,6 +1,6 @@
"use client"; "use client";
import { format, subDays, subYears } from "date-fns"; import { addDays, format, subDays, subYears } from "date-fns";
import { Calendar as CalendarIcon } from "lucide-react"; import { Calendar as CalendarIcon } from "lucide-react";
import type { FC } from "react"; import type { FC } from "react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
@ -14,6 +14,7 @@ interface DateRangeSelectorProps {
endDate: Date | undefined; endDate: Date | undefined;
onStartDateChange: (date: Date | undefined) => void; onStartDateChange: (date: Date | undefined) => void;
onEndDateChange: (date: Date | undefined) => void; onEndDateChange: (date: Date | undefined) => void;
allowFutureDates?: boolean; // Allow future dates for calendar connectors
} }
export const DateRangeSelector: FC<DateRangeSelectorProps> = ({ export const DateRangeSelector: FC<DateRangeSelectorProps> = ({
@ -21,6 +22,7 @@ export const DateRangeSelector: FC<DateRangeSelectorProps> = ({
endDate, endDate,
onStartDateChange, onStartDateChange,
onEndDateChange, onEndDateChange,
allowFutureDates = false,
}) => { }) => {
const handleLast30Days = () => { const handleLast30Days = () => {
const today = new Date(); const today = new Date();
@ -28,6 +30,12 @@ export const DateRangeSelector: FC<DateRangeSelectorProps> = ({
onEndDateChange(today); onEndDateChange(today);
}; };
const handleNext30Days = () => {
const today = new Date();
onStartDateChange(today);
onEndDateChange(addDays(today, 30));
};
const handleLastYear = () => { const handleLastYear = () => {
const today = new Date(); const today = new Date();
onStartDateChange(subYears(today, 1)); onStartDateChange(subYears(today, 1));
@ -43,8 +51,9 @@ export const DateRangeSelector: FC<DateRangeSelectorProps> = ({
<div className="rounded-xl bg-slate-400/5 dark:bg-white/5 p-3 sm:p-6"> <div className="rounded-xl bg-slate-400/5 dark:bg-white/5 p-3 sm:p-6">
<h3 className="font-medium text-sm sm:text-base mb-4">Select Date Range</h3> <h3 className="font-medium text-sm sm:text-base mb-4">Select Date Range</h3>
<p className="text-xs sm:text-sm text-muted-foreground mb-6"> <p className="text-xs sm:text-sm text-muted-foreground mb-6">
Choose how far back you want to sync your data. You can always re-index later with different {allowFutureDates
dates. ? "Choose the date range to sync your data. You can select future dates to index upcoming events."
: "Choose how far back you want to sync your data. You can always re-index later with different dates."}
</p> </p>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4"> <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
@ -72,7 +81,7 @@ export const DateRangeSelector: FC<DateRangeSelectorProps> = ({
mode="single" mode="single"
selected={startDate} selected={startDate}
onSelect={onStartDateChange} onSelect={onStartDateChange}
disabled={(date) => date > new Date()} disabled={allowFutureDates ? false : (date) => date > new Date()}
/> />
</PopoverContent> </PopoverContent>
</Popover> </Popover>
@ -94,7 +103,9 @@ export const DateRangeSelector: FC<DateRangeSelectorProps> = ({
)} )}
> >
<CalendarIcon className="mr-2 h-4 w-4" /> <CalendarIcon className="mr-2 h-4 w-4" />
{endDate ? format(endDate, "PPP") : "Default (Today)"} {endDate
? format(endDate, "PPP")
: "Default (Today)"}
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent className="w-auto p-0 z-[100]" align="start"> <PopoverContent className="w-auto p-0 z-[100]" align="start">
@ -102,7 +113,11 @@ export const DateRangeSelector: FC<DateRangeSelectorProps> = ({
mode="single" mode="single"
selected={endDate} selected={endDate}
onSelect={onEndDateChange} onSelect={onEndDateChange}
disabled={(date) => date > new Date() || (startDate ? date < startDate : false)} disabled={
allowFutureDates
? (date) => (startDate ? date < startDate : false)
: (date) => date > new Date() || (startDate ? date < startDate : false)
}
/> />
</PopoverContent> </PopoverContent>
</Popover> </Popover>
@ -129,6 +144,17 @@ export const DateRangeSelector: FC<DateRangeSelectorProps> = ({
> >
Last 30 Days Last 30 Days
</Button> </Button>
{allowFutureDates && (
<Button
type="button"
variant="outline"
size="sm"
onClick={handleNext30Days}
className="text-xs sm:text-sm bg-slate-400/5 dark:bg-slate-400/5 border-slate-400/20 hover:bg-slate-400/10 dark:hover:bg-slate-400/10"
>
Next 30 Days
</Button>
)}
<Button <Button
type="button" type="button"
variant="outline" variant="outline"

View file

@ -173,6 +173,7 @@ export const LumaConnectForm: FC<ConnectFormProps> = ({ onSubmit, isSubmitting }
endDate={endDate} endDate={endDate}
onStartDateChange={setStartDate} onStartDateChange={setStartDate}
onEndDateChange={setEndDate} onEndDateChange={setEndDate}
allowFutureDates={true}
/> />
{/* Periodic Sync Config */} {/* Periodic Sync Config */}

View file

@ -209,6 +209,10 @@ export const ConnectorEditView: FC<ConnectorEditViewProps> = ({
endDate={endDate} endDate={endDate}
onStartDateChange={onStartDateChange} onStartDateChange={onStartDateChange}
onEndDateChange={onEndDateChange} onEndDateChange={onEndDateChange}
allowFutureDates={
connector.connector_type === "GOOGLE_CALENDAR_CONNECTOR" ||
connector.connector_type === "LUMA_CONNECTOR"
}
/> />
)} )}

View file

@ -150,6 +150,10 @@ export const IndexingConfigurationView: FC<IndexingConfigurationViewProps> = ({
endDate={endDate} endDate={endDate}
onStartDateChange={onStartDateChange} onStartDateChange={onStartDateChange}
onEndDateChange={onEndDateChange} onEndDateChange={onEndDateChange}
allowFutureDates={
config.connectorType === "GOOGLE_CALENDAR_CONNECTOR" ||
config.connectorType === "LUMA_CONNECTOR"
}
/> />
)} )}