diff --git a/packages/twenty-front/src/modules/client-config/components/ClientConfigProviderEffect.tsx b/packages/twenty-front/src/modules/client-config/components/ClientConfigProviderEffect.tsx index ebbfa965ead7..3e52123cc1e2 100644 --- a/packages/twenty-front/src/modules/client-config/components/ClientConfigProviderEffect.tsx +++ b/packages/twenty-front/src/modules/client-config/components/ClientConfigProviderEffect.tsx @@ -82,7 +82,7 @@ export const ClientConfigProviderEffect = () => { magicLink: false, sso: data?.clientConfig.authProviders.sso, }); - setIsDebugMode(data?.clientConfig.debugMode); + // setIsDebugMode(data?.clientConfig.debugMode); setIsAnalyticsEnabled(data?.clientConfig.analyticsEnabled); setIsDeveloperDefaultSignInPrefilled(data?.clientConfig.signInPrefilled); setIsMultiWorkspaceEnabled(data?.clientConfig.isMultiWorkspaceEnabled); diff --git a/packages/twenty-front/src/modules/client-config/states/isDebugModeState.ts b/packages/twenty-front/src/modules/client-config/states/isDebugModeState.ts index b2efbf8fc883..d38539d045f5 100644 --- a/packages/twenty-front/src/modules/client-config/states/isDebugModeState.ts +++ b/packages/twenty-front/src/modules/client-config/states/isDebugModeState.ts @@ -2,5 +2,5 @@ import { createState } from 'twenty-ui'; export const isDebugModeState = createState({ key: 'isDebugModeState', - defaultValue: false, + defaultValue: true, }); diff --git a/packages/twenty-front/src/modules/debug/components/RecoilDebugObserver.tsx b/packages/twenty-front/src/modules/debug/components/RecoilDebugObserver.tsx index f6ce486937b0..6bb149452ae7 100644 --- a/packages/twenty-front/src/modules/debug/components/RecoilDebugObserver.tsx +++ b/packages/twenty-front/src/modules/debug/components/RecoilDebugObserver.tsx @@ -17,6 +17,8 @@ const formatTitle = (stateName: string) => { export const RecoilDebugObserverEffect = () => { const isDebugMode = useRecoilValue(isDebugModeState); + console.log({ isDebugMode }); + useRecoilTransactionObserver_UNSTABLE(({ snapshot }) => { if (!isDebugMode) { return; diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormDateFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormDateFieldInput.tsx index 60c0985d9f7f..6205339d41dc 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormDateFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormDateFieldInput.tsx @@ -3,7 +3,8 @@ import { FormFieldInputInputContainer } from '@/object-record/record-field/form- import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer'; import { VariableChip } from '@/object-record/record-field/form-types/components/VariableChip'; import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent'; -import { DateInput } from '@/ui/field/input/components/DateInput'; +import { DateInputStandalone } from '@/ui/field/input/components/DateInputStandalone'; +import { dateInputStandaloneInternalValueFamilyState } from '@/ui/field/input/states/dateInputStandaloneInternalValueState'; import { InputLabel } from '@/ui/input/components/InputLabel'; import { MAX_DATE } from '@/ui/input/components/internal/date/constants/MaxDate'; import { MIN_DATE } from '@/ui/input/components/internal/date/constants/MinDate'; @@ -21,6 +22,7 @@ import { useRef, useState, } from 'react'; +import { useSetRecoilState } from 'recoil'; import { isDefined, Nullable, TEXT_INPUT_STYLE } from 'twenty-ui'; const StyledInputContainer = styled(FormFieldInputInputContainer)` @@ -95,10 +97,14 @@ export const FormDateFieldInput = ({ ? new Date(draftValue.value) : null; - const datePickerWrapperRef = useRef(null); + const setDateInputStandaloneInternalValue = useSetRecoilState( + dateInputStandaloneInternalValueFamilyState({ + inputId, + defaultDate: draftValueAsDate, + }), + ); - const [temporaryValue, setTemporaryValue] = - useState>(draftValueAsDate); + const datePickerWrapperRef = useRef(null); const [inputDateTime, setInputDateTime] = useState( isDefined(draftValueAsDate) && !isStandaloneVariableString(defaultValue) @@ -167,7 +173,7 @@ export const FormDateFieldInput = ({ mode: 'view', }); - setTemporaryValue(null); + setDateInputStandaloneInternalValue(null); setInputDateTime(''); @@ -182,7 +188,7 @@ export const FormDateFieldInput = ({ mode: 'view', }); - setTemporaryValue(newDate); + setDateInputStandaloneInternalValue(newDate); setInputDateTime( isDefined(newDate) @@ -245,7 +251,7 @@ export const FormDateFieldInput = ({ mode: 'edit', }); - setTemporaryValue(validatedDate); + setDateInputStandaloneInternalValue(validatedDate); setInputDateTime( parseDateToString({ @@ -276,7 +282,7 @@ export const FormDateFieldInput = ({ mode: 'view', }); - setTemporaryValue(null); + setDateInputStandaloneInternalValue(null); onPersist(null); }; @@ -304,7 +310,9 @@ export const FormDateFieldInput = ({ {draftValue.mode === 'edit' ? ( - diff --git a/packages/twenty-front/src/modules/ui/field/input/components/DateInput.tsx b/packages/twenty-front/src/modules/ui/field/input/components/DateInput.tsx index 0fce5dcb228e..29ed4c18ce7d 100644 --- a/packages/twenty-front/src/modules/ui/field/input/components/DateInput.tsx +++ b/packages/twenty-front/src/modules/ui/field/input/components/DateInput.tsx @@ -9,6 +9,7 @@ import { } from '@/ui/input/components/internal/date/components/InternalDatePicker'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; +import { useRef, useState } from 'react'; const StyledCalendarContainer = styled.div` background: ${({ theme }) => theme.background.transparent.secondary}; @@ -19,6 +20,7 @@ const StyledCalendarContainer = styled.div` `; export type DateInputProps = { + value: Nullable; onEnter: (newDate: Nullable) => void; onEscape: (newDate: Nullable) => void; onClickOutside: ( @@ -31,12 +33,10 @@ export type DateInputProps = { onClear?: () => void; onSubmit?: (newDate: Nullable) => void; hideHeaderInput?: boolean; - temporaryValue: Nullable; - setTemporaryValue: (newValue: Nullable) => void; - wrapperRef: React.RefObject; }; export const DateInput = ({ + value, onEnter, onEscape, onClickOutside, @@ -46,22 +46,23 @@ export const DateInput = ({ onClear, onSubmit, hideHeaderInput, - wrapperRef, - temporaryValue, - setTemporaryValue, }: DateInputProps) => { + const [internalValue, setInternalValue] = useState(value); + + const wrapperRef = useRef(null); + const handleChange = (newDate: Date | null) => { - setTemporaryValue(newDate); + setInternalValue(newDate); onChange?.(newDate); }; const handleClear = () => { - setTemporaryValue(null); + setInternalValue(null); onClear?.(); }; const handleMouseSelect = (newDate: Date | null) => { - setTemporaryValue(newDate); + setInternalValue(newDate); onSubmit?.(newDate); }; @@ -78,26 +79,29 @@ export const DateInput = ({ listenerId: 'DateInput', callback: (event) => { event.stopImmediatePropagation(); + closeDropdownYearSelect(); closeDropdownMonthSelect(); closeDropdown(); - onClickOutside(event, temporaryValue); + onClickOutside(event, internalValue); }, }); return ( - - - +
+ + + +
); }; diff --git a/packages/twenty-front/src/modules/ui/field/input/components/DateInputStandalone.tsx b/packages/twenty-front/src/modules/ui/field/input/components/DateInputStandalone.tsx new file mode 100644 index 000000000000..a12c32b207ca --- /dev/null +++ b/packages/twenty-front/src/modules/ui/field/input/components/DateInputStandalone.tsx @@ -0,0 +1,116 @@ +import styled from '@emotion/styled'; +import { Nullable } from 'twenty-ui'; + +import { dateInputStandaloneInternalValueFamilyState } from '@/ui/field/input/states/dateInputStandaloneInternalValueState'; +import { + InternalDatePicker, + MONTH_AND_YEAR_DROPDOWN_ID, + MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID, + MONTH_AND_YEAR_DROPDOWN_YEAR_SELECT_ID, +} from '@/ui/input/components/internal/date/components/InternalDatePicker'; +import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; +import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; +import { useRef } from 'react'; +import { useRecoilState } from 'recoil'; + +const StyledCalendarContainer = styled.div` + background: ${({ theme }) => theme.background.transparent.secondary}; + backdrop-filter: ${({ theme }) => theme.blur.medium}; + border: 1px solid ${({ theme }) => theme.border.color.light}; + border-radius: ${({ theme }) => theme.border.radius.md}; + box-shadow: ${({ theme }) => theme.boxShadow.strong}; +`; + +export type DateInputStandaloneProps = { + inputId: string; + defaultValue: Nullable; + onEnter: (newDate: Nullable) => void; + onEscape: (newDate: Nullable) => void; + onClickOutside: ( + event: MouseEvent | TouchEvent, + newDate: Nullable, + ) => void; + clearable?: boolean; + onChange?: (newDate: Nullable) => void; + isDateTimeInput?: boolean; + onClear?: () => void; + onSubmit?: (newDate: Nullable) => void; + hideHeaderInput?: boolean; +}; + +export const DateInputStandalone = ({ + inputId, + defaultValue, + onEnter, + onEscape, + onClickOutside, + clearable, + onChange, + isDateTimeInput, + onClear, + onSubmit, + hideHeaderInput, +}: DateInputStandaloneProps) => { + const [internalValue, setInternalValue] = useRecoilState( + dateInputStandaloneInternalValueFamilyState({ + inputId, + defaultDate: defaultValue, + }), + ); + + const wrapperRef = useRef(null); + + const handleChange = (newDate: Date | null) => { + setInternalValue(newDate); + onChange?.(newDate); + }; + + const handleClear = () => { + setInternalValue(null); + onClear?.(); + }; + + const handleMouseSelect = (newDate: Date | null) => { + setInternalValue(newDate); + onSubmit?.(newDate); + }; + + const { closeDropdown } = useDropdown(MONTH_AND_YEAR_DROPDOWN_ID); + const { closeDropdown: closeDropdownMonthSelect } = useDropdown( + MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID, + ); + const { closeDropdown: closeDropdownYearSelect } = useDropdown( + MONTH_AND_YEAR_DROPDOWN_YEAR_SELECT_ID, + ); + + useListenClickOutside({ + refs: [wrapperRef], + listenerId: 'DateInput', + callback: (event) => { + event.stopImmediatePropagation(); + + closeDropdownYearSelect(); + closeDropdownMonthSelect(); + closeDropdown(); + onClickOutside(event, internalValue); + }, + }); + + return ( +
+ + + +
+ ); +}; diff --git a/packages/twenty-front/src/modules/ui/field/input/states/dateInputStandaloneInternalValueState.ts b/packages/twenty-front/src/modules/ui/field/input/states/dateInputStandaloneInternalValueState.ts new file mode 100644 index 000000000000..b778d1c10e34 --- /dev/null +++ b/packages/twenty-front/src/modules/ui/field/input/states/dateInputStandaloneInternalValueState.ts @@ -0,0 +1,15 @@ +import { atomFamily } from 'recoil'; +import { Nullable } from 'twenty-ui'; + +type DateInputStandaloneInternalValueFamilyStateKey = { + inputId: string; + defaultDate: Nullable; +}; + +export const dateInputStandaloneInternalValueFamilyState = atomFamily< + Nullable, + DateInputStandaloneInternalValueFamilyStateKey +>({ + key: 'dateInputStandaloneInternalValueFamilyState', + default: (param) => param.defaultDate, +});