From e8c7dd8380ab25d77824951689866384bb01fd92 Mon Sep 17 00:00:00 2001 From: Weiko Date: Mon, 15 Sep 2025 16:43:52 +0200 Subject: [PATCH] add date picker on calendar view (#14511) Screenshot 2025-09-15 at 16 34 50 --- .../components/RecordCalendarTopBar.tsx | 147 +++++++++++++++--- .../RecordIndexCalendarDataLoaderEffect.tsx | 10 +- ...ecordCalendarSelectedDateComponentState.ts | 9 ++ 3 files changed, 142 insertions(+), 24 deletions(-) create mode 100644 packages/twenty-front/src/modules/object-record/record-calendar/states/recordCalendarSelectedDateComponentState.ts diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/components/RecordCalendarTopBar.tsx b/packages/twenty-front/src/modules/object-record/record-calendar/components/RecordCalendarTopBar.tsx index 9fd69dfbfb..b866d89d21 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/components/RecordCalendarTopBar.tsx +++ b/packages/twenty-front/src/modules/object-record/record-calendar/components/RecordCalendarTopBar.tsx @@ -1,14 +1,42 @@ import { RecordCalendarComponentInstanceContext } from '@/object-record/record-calendar/states/contexts/RecordCalendarComponentInstanceContext'; +import { recordCalendarSelectedDateComponentState } from '@/object-record/record-calendar/states/recordCalendarSelectedDateComponentState'; import { recordIndexCalendarLayoutState } from '@/object-record/record-index/states/recordIndexCalendarLayoutState'; +import { DateTimePicker } from '@/ui/input/components/internal/date/components/InternalDatePicker'; import { Select } from '@/ui/input/components/Select'; +import { SelectControl } from '@/ui/input/components/SelectControl'; +import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; +import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent'; +import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown'; +import { type DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset'; import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow'; +import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState'; import styled from '@emotion/styled'; +import { addMonths, format, subMonths } from 'date-fns'; import { useRecoilValue } from 'recoil'; +import { type Nullable } from 'twenty-shared/types'; +import { isDefined } from 'twenty-shared/utils'; +import { IconChevronLeft, IconChevronRight } from 'twenty-ui/display'; +import { Button } from 'twenty-ui/input'; import { ViewCalendarLayout } from '~/generated/graphql'; const StyledContainer = styled.div` + align-items: center; display: flex; height: 24px; + justify-content: space-between; + width: 100%; +`; + +const StyledLeftSection = styled.div` + display: flex; + align-items: center; + gap: ${({ theme }) => theme.spacing(2)}; +`; + +const StyledNavigationSection = styled.div` + display: flex; + align-items: center; + gap: ${({ theme }) => theme.spacing(1)}; `; export const RecordCalendarTopBar = () => { @@ -20,29 +48,106 @@ export const RecordCalendarTopBar = () => { recordIndexCalendarLayoutState, ); + const [recordCalendarSelectedDate, setRecordCalendarSelectedDate] = + useRecoilComponentState(recordCalendarSelectedDateComponentState); + + const datePickerDropdownId = `record-calendar-date-picker-${recordCalendarId}`; + const { closeDropdown } = useCloseDropdown(); + + const handleDateChange = (date: Nullable) => { + if (isDefined(date)) { + setRecordCalendarSelectedDate(date); + } + closeDropdown(datePickerDropdownId); + }; + + const handlePreviousMonth = () => { + setRecordCalendarSelectedDate(subMonths(recordCalendarSelectedDate, 1)); + }; + + const handleNextMonth = () => { + setRecordCalendarSelectedDate(addMonths(recordCalendarSelectedDate, 1)); + }; + + const handleTodayClick = () => { + setRecordCalendarSelectedDate(new Date()); + }; + + const formattedDate = format(recordCalendarSelectedDate, 'MMMM yyyy'); + + const dropdownContentOffset = { x: 140, y: 0 } satisfies DropdownOffset; + return ( - {}} + /> + + } + dropdownComponents={ + + + + } + dropdownOffset={dropdownContentOffset} + /> + + + +