+2
-2
@@ -16,7 +16,7 @@ import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useContext } from 'react';
|
||||
import { type ViewFilterOperand } from 'twenty-shared/types';
|
||||
@@ -48,7 +48,7 @@ export const AdvancedFilterRecordFilterOperandSelectContent = ({
|
||||
applyObjectFilterDropdownOperand(operand);
|
||||
};
|
||||
|
||||
const selectedItemId = useRecoilComponentValue(
|
||||
const selectedItemId = useRecoilComponentValueV2(
|
||||
selectedItemIdComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
@@ -83,7 +84,7 @@ export const AdvancedFilterSubFieldSelectMenu = ({
|
||||
const { advancedFilterFieldSelectDropdownId } =
|
||||
useAdvancedFilterFieldSelectDropdown(recordFilterId);
|
||||
|
||||
const selectedItemId = useRecoilComponentValue(
|
||||
const selectedItemId = useRecoilComponentValueV2(
|
||||
selectedItemIdComponentState,
|
||||
advancedFilterFieldSelectDropdownId,
|
||||
);
|
||||
|
||||
+4
-4
@@ -2,8 +2,8 @@ import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataIte
|
||||
import { FILTER_FIELD_LIST_ID } from '@/object-record/object-filter-dropdown/constants/FilterFieldListId';
|
||||
import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType';
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
import { isSelectedItemIdComponentFamilySelector } from '@/ui/layout/selectable-list/states/selectors/isSelectedItemIdComponentFamilySelector';
|
||||
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
|
||||
import { isSelectedItemIdComponentFamilyState } from '@/ui/layout/selectable-list/states/isSelectedItemIdComponentFamilyState';
|
||||
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentFamilyValueV2';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
|
||||
@@ -18,8 +18,8 @@ export const ObjectFilterDropdownFilterSelectMenuItem = ({
|
||||
}: ObjectFilterDropdownFilterSelectMenuItemProps) => {
|
||||
const { resetSelectedItem } = useSelectableList(FILTER_FIELD_LIST_ID);
|
||||
|
||||
const isSelectedItem = useRecoilComponentFamilyValue(
|
||||
isSelectedItemIdComponentFamilySelector,
|
||||
const isSelectedItem = useRecoilComponentFamilyValueV2(
|
||||
isSelectedItemIdComponentFamilyState,
|
||||
fieldMetadataItemToSelect.id,
|
||||
);
|
||||
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states
|
||||
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { MAX_OPTIONS_TO_DISPLAY } from 'twenty-shared/constants';
|
||||
@@ -68,7 +69,7 @@ export const ObjectFilterDropdownOptionSelect = ({
|
||||
|
||||
const { resetSelectedItem } = useSelectableList(componentInstanceId);
|
||||
|
||||
const selectedItemId = useRecoilComponentValue(
|
||||
const selectedItemId = useRecoilComponentValueV2(
|
||||
selectedItemIdComponentState,
|
||||
componentInstanceId,
|
||||
);
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
@@ -32,7 +32,7 @@ export const ObjectOptionsDropdownCalendarViewContent = () => {
|
||||
);
|
||||
const { updateCurrentView } = useUpdateCurrentView();
|
||||
|
||||
const selectedItemId = useRecoilComponentValue(
|
||||
const selectedItemId = useRecoilComponentValueV2(
|
||||
selectedItemIdComponentState,
|
||||
OBJECT_OPTIONS_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
+2
-1
@@ -13,6 +13,7 @@ import { SelectableListItem } from '@/ui/layout/selectable-list/components/Selec
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
|
||||
import { ViewKey } from '@/views/types/ViewKey';
|
||||
import { ViewType, viewTypeIconMapping } from '@/views/types/ViewType';
|
||||
@@ -104,7 +105,7 @@ export const ObjectOptionsDropdownCustomView = ({
|
||||
'Delete view',
|
||||
];
|
||||
|
||||
const selectedItemId = useRecoilComponentValue(
|
||||
const selectedItemId = useRecoilComponentValueV2(
|
||||
selectedItemIdComponentState,
|
||||
OBJECT_OPTIONS_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
+2
-1
@@ -9,6 +9,7 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
|
||||
import { useOpenCreateViewDropdown } from '@/views/hooks/useOpenCreateViewDropown';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
@@ -41,7 +42,7 @@ export const ObjectOptionsDropdownDefaultView = () => {
|
||||
'Create custom view',
|
||||
];
|
||||
|
||||
const selectedItemId = useRecoilComponentValue(
|
||||
const selectedItemId = useRecoilComponentValueV2(
|
||||
selectedItemIdComponentState,
|
||||
OBJECT_OPTIONS_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
+2
-1
@@ -14,6 +14,7 @@ import { SelectableList } from '@/ui/layout/selectable-list/components/Selectabl
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
|
||||
import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
|
||||
import { type GraphQLView } from '@/views/types/GraphQLView';
|
||||
@@ -124,7 +125,7 @@ export const ObjectOptionsDropdownLayoutContent = () => {
|
||||
...(currentView?.type !== ViewType.Table ? ['Compact view'] : []),
|
||||
];
|
||||
|
||||
const selectedItemId = useRecoilComponentValue(
|
||||
const selectedItemId = useRecoilComponentValueV2(
|
||||
selectedItemIdComponentState,
|
||||
OBJECT_OPTIONS_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
|
||||
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
|
||||
import { t } from '@lingui/core/macro';
|
||||
@@ -33,7 +33,7 @@ export const ObjectOptionsDropdownLayoutOpenInContent = () => {
|
||||
objectMetadataItem.nameSingular,
|
||||
);
|
||||
|
||||
const selectedItemId = useRecoilComponentValue(
|
||||
const selectedItemId = useRecoilComponentValueV2(
|
||||
selectedItemIdComponentState,
|
||||
OBJECT_OPTIONS_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
+2
-1
@@ -14,6 +14,7 @@ import { SelectableListItem } from '@/ui/layout/selectable-list/components/Selec
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import {
|
||||
IconChevronLeft,
|
||||
@@ -38,7 +39,7 @@ export const ObjectOptionsDropdownRecordGroupSortContent = () => {
|
||||
setRecordGroupSort(sort);
|
||||
};
|
||||
|
||||
const selectedItemId = useRecoilComponentValue(
|
||||
const selectedItemId = useRecoilComponentValueV2(
|
||||
selectedItemIdComponentState,
|
||||
OBJECT_OPTIONS_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ import { SelectableListItem } from '@/ui/layout/selectable-list/components/Selec
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
|
||||
import { useGetAvailableFieldsToGroupRecordsBy } from '@/views/view-picker/hooks/useGetAvailableFieldsToGroupRecordsBy';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
@@ -90,7 +91,7 @@ export const ObjectOptionsDropdownRecordGroupsContent = () => {
|
||||
}
|
||||
}, [hiddenRecordGroupIds, currentContentId, onContentChange]);
|
||||
|
||||
const selectedItemId = useRecoilComponentValue(
|
||||
const selectedItemId = useRecoilComponentValueV2(
|
||||
selectedItemIdComponentState,
|
||||
OBJECT_OPTIONS_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@ import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/Gene
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useCanPersistViewChanges } from '@/views/hooks/useCanPersistViewChanges';
|
||||
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
|
||||
import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
|
||||
@@ -39,7 +39,7 @@ export const ObjectOptionsDropdownVisibilityContent = () => {
|
||||
const hasViewsPermission = useHasPermissionFlag(PermissionFlagType.VIEWS);
|
||||
const { canPersistChanges } = useCanPersistViewChanges();
|
||||
|
||||
const selectedItemId = useRecoilComponentValue(
|
||||
const selectedItemId = useRecoilComponentValueV2(
|
||||
selectedItemIdComponentState,
|
||||
OBJECT_OPTIONS_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
+5
-3
@@ -1,7 +1,7 @@
|
||||
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
|
||||
import { recordIndexOpenRecordInStateV2 } from '@/object-record/record-index/states/recordIndexOpenRecordInStateV2';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { useStore } from 'jotai';
|
||||
import { useUpdateCurrentView } from '@/views/hooks/useUpdateCurrentView';
|
||||
import { type GraphQLView } from '@/views/types/GraphQLView';
|
||||
import { type ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
|
||||
@@ -11,6 +11,8 @@ import { useCallback } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
|
||||
export const useUpdateObjectViewOptions = () => {
|
||||
const store = useStore();
|
||||
|
||||
const setRecordIndexOpenRecordIn = useSetRecoilState(
|
||||
recordIndexOpenRecordInState,
|
||||
);
|
||||
@@ -29,12 +31,12 @@ export const useUpdateObjectViewOptions = () => {
|
||||
(openRecordIn: ViewOpenRecordInType, view: GraphQLView | undefined) => {
|
||||
if (!view) return;
|
||||
setRecordIndexOpenRecordIn(openRecordIn);
|
||||
jotaiStore.set(recordIndexOpenRecordInStateV2.atom, openRecordIn);
|
||||
store.set(recordIndexOpenRecordInStateV2.atom, openRecordIn);
|
||||
updateCurrentView({
|
||||
openRecordIn,
|
||||
});
|
||||
},
|
||||
[setRecordIndexOpenRecordIn, updateCurrentView],
|
||||
[setRecordIndexOpenRecordIn, updateCurrentView, store],
|
||||
);
|
||||
|
||||
const setAndPersistViewName = useCallback(
|
||||
|
||||
+3
-2
@@ -29,6 +29,7 @@ import { useRecoilComponentState } from '@/ui/utilities/state/component-state/ho
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/jotai/hooks/useSetRecoilComponentStateV2';
|
||||
import { Trans, useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { findByProperty } from 'twenty-shared/utils';
|
||||
@@ -151,12 +152,12 @@ export const ObjectSortDropdownButton = () => {
|
||||
...hiddenFieldMetadataItemsSorted.map((item) => item.id),
|
||||
];
|
||||
|
||||
const selectedItemId = useRecoilComponentValue(
|
||||
const selectedItemId = useRecoilComponentValueV2(
|
||||
selectedItemIdComponentState,
|
||||
OBJECT_SORT_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
const setSelectedItemId = useSetRecoilComponentState(
|
||||
const setSelectedItemId = useSetRecoilComponentStateV2(
|
||||
selectedItemIdComponentState,
|
||||
OBJECT_SORT_DROPDOWN_ID,
|
||||
);
|
||||
|
||||
+2
-1
@@ -15,6 +15,7 @@ import { RECORD_INDEX_REMOVE_SORTING_MODAL_ID } from '@/object-record/record-ind
|
||||
|
||||
import { isModalOpenedComponentState } from '@/ui/layout/modal/states/isModalOpenedComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
type RecordBoardContainerProps = {
|
||||
@@ -55,7 +56,7 @@ export const RecordBoardContainer = ({
|
||||
...args,
|
||||
});
|
||||
|
||||
const isRecordIndexRemoveSortingModalOpened = useRecoilComponentValue(
|
||||
const isRecordIndexRemoveSortingModalOpened = useRecoilComponentValueV2(
|
||||
isModalOpenedComponentState,
|
||||
RECORD_INDEX_REMOVE_SORTING_MODAL_ID,
|
||||
);
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
import { scrollWrapperScrollTopComponentState } from '@/ui/utilities/scroll/states/scrollWrapperScrollTopComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export const RecordBoardStickyHeaderEffect = () => {
|
||||
const scrollTop = useRecoilComponentValue(
|
||||
const scrollTop = useRecoilComponentValueV2(
|
||||
scrollWrapperScrollTopComponentState,
|
||||
);
|
||||
|
||||
|
||||
+16
-17
@@ -11,8 +11,8 @@ import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlin
|
||||
import { currentFocusIdSelector } from '@/ui/utilities/focus/states/currentFocusIdSelector';
|
||||
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
type RecordBoardCardInputContextProviderProps = {
|
||||
children: React.ReactNode;
|
||||
@@ -21,6 +21,7 @@ type RecordBoardCardInputContextProviderProps = {
|
||||
export const RecordBoardCardInputContextProvider = ({
|
||||
children,
|
||||
}: RecordBoardCardInputContextProviderProps) => {
|
||||
const store = useStore();
|
||||
const { closeInlineCell } = useInlineCell();
|
||||
const setRecordBoardCardEditModePosition = useSetRecoilComponentState(
|
||||
recordBoardCardEditModePositionComponentState,
|
||||
@@ -58,29 +59,27 @@ export const RecordBoardCardInputContextProvider = ({
|
||||
closeInlineCellAndResetEditModePosition();
|
||||
};
|
||||
|
||||
const handleClickOutside: FieldInputClickOutsideEvent = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
({ newValue, event, skipPersist }) => {
|
||||
const currentFocusId = snapshot
|
||||
.getLoadable(currentFocusIdSelector)
|
||||
.getValue();
|
||||
const handleClickOutside: FieldInputClickOutsideEvent = useCallback(
|
||||
({ newValue, event, skipPersist }) => {
|
||||
const currentFocusId = store.get(currentFocusIdSelector.atom);
|
||||
|
||||
if (currentFocusId !== instanceId) {
|
||||
return;
|
||||
}
|
||||
event?.preventDefault();
|
||||
event?.stopImmediatePropagation();
|
||||
if (currentFocusId !== instanceId) {
|
||||
return;
|
||||
}
|
||||
event?.preventDefault();
|
||||
event?.stopImmediatePropagation();
|
||||
|
||||
if (skipPersist !== true) {
|
||||
persistFieldFromFieldInputContext(newValue);
|
||||
}
|
||||
if (skipPersist !== true) {
|
||||
persistFieldFromFieldInputContext(newValue);
|
||||
}
|
||||
|
||||
closeInlineCellAndResetEditModePosition();
|
||||
},
|
||||
closeInlineCellAndResetEditModePosition();
|
||||
},
|
||||
[
|
||||
closeInlineCellAndResetEditModePosition,
|
||||
instanceId,
|
||||
persistFieldFromFieldInputContext,
|
||||
store,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
+16
-17
@@ -11,8 +11,8 @@ import { useInlineCell } from '@/object-record/record-inline-cell/hooks/useInlin
|
||||
import { currentFocusIdSelector } from '@/ui/utilities/focus/states/currentFocusIdSelector';
|
||||
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
type RecordCalendarCardInputContextProviderProps = {
|
||||
children: React.ReactNode;
|
||||
@@ -21,6 +21,7 @@ type RecordCalendarCardInputContextProviderProps = {
|
||||
export const RecordCalendarCardInputContextProvider = ({
|
||||
children,
|
||||
}: RecordCalendarCardInputContextProviderProps) => {
|
||||
const store = useStore();
|
||||
const { closeInlineCell } = useInlineCell();
|
||||
const setRecordCalendarCardEditModePosition = useSetRecoilComponentState(
|
||||
recordCalendarCardEditModePositionComponentState,
|
||||
@@ -58,29 +59,27 @@ export const RecordCalendarCardInputContextProvider = ({
|
||||
closeInlineCellAndResetEditModePosition();
|
||||
};
|
||||
|
||||
const handleClickOutside: FieldInputClickOutsideEvent = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
({ newValue, event, skipPersist }) => {
|
||||
const currentFocusId = snapshot
|
||||
.getLoadable(currentFocusIdSelector)
|
||||
.getValue();
|
||||
const handleClickOutside: FieldInputClickOutsideEvent = useCallback(
|
||||
({ newValue, event, skipPersist }) => {
|
||||
const currentFocusId = store.get(currentFocusIdSelector.atom);
|
||||
|
||||
if (currentFocusId !== instanceId) {
|
||||
return;
|
||||
}
|
||||
event?.preventDefault();
|
||||
event?.stopImmediatePropagation();
|
||||
if (currentFocusId !== instanceId) {
|
||||
return;
|
||||
}
|
||||
event?.preventDefault();
|
||||
event?.stopImmediatePropagation();
|
||||
|
||||
if (skipPersist !== true) {
|
||||
persistFieldFromFieldInputContext(newValue);
|
||||
}
|
||||
if (skipPersist !== true) {
|
||||
persistFieldFromFieldInputContext(newValue);
|
||||
}
|
||||
|
||||
closeInlineCellAndResetEditModePosition();
|
||||
},
|
||||
closeInlineCellAndResetEditModePosition();
|
||||
},
|
||||
[
|
||||
closeInlineCellAndResetEditModePosition,
|
||||
instanceId,
|
||||
persistFieldFromFieldInputContext,
|
||||
store,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
+16
-17
@@ -14,8 +14,8 @@ import { useOpenFieldInputEditMode } from '@/object-record/record-field/ui/hooks
|
||||
import { currentFocusIdSelector } from '@/ui/utilities/focus/states/currentFocusIdSelector';
|
||||
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
type RecordFieldListInputContextProviderProps = {
|
||||
children: React.ReactNode;
|
||||
@@ -32,6 +32,7 @@ export const RecordFieldListInputContextProvider = ({
|
||||
objectMetadataItem,
|
||||
instanceIdPrefix,
|
||||
}: RecordFieldListInputContextProviderProps) => {
|
||||
const store = useStore();
|
||||
const instanceId = useAvailableComponentInstanceId(
|
||||
RecordFieldComponentInstanceContext,
|
||||
);
|
||||
@@ -86,29 +87,27 @@ export const RecordFieldListInputContextProvider = ({
|
||||
closeInlineCellAndResetEditModePosition();
|
||||
};
|
||||
|
||||
const handleClickOutside: FieldInputClickOutsideEvent = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
({ newValue, event, skipPersist }) => {
|
||||
const currentFocusId = snapshot
|
||||
.getLoadable(currentFocusIdSelector)
|
||||
.getValue();
|
||||
const handleClickOutside: FieldInputClickOutsideEvent = useCallback(
|
||||
({ newValue, event, skipPersist }) => {
|
||||
const currentFocusId = store.get(currentFocusIdSelector.atom);
|
||||
|
||||
if (currentFocusId !== instanceId) {
|
||||
return;
|
||||
}
|
||||
event?.preventDefault();
|
||||
event?.stopImmediatePropagation();
|
||||
if (currentFocusId !== instanceId) {
|
||||
return;
|
||||
}
|
||||
event?.preventDefault();
|
||||
event?.stopImmediatePropagation();
|
||||
|
||||
if (skipPersist !== true) {
|
||||
persistFieldFromFieldInputContext(newValue);
|
||||
}
|
||||
if (skipPersist !== true) {
|
||||
persistFieldFromFieldInputContext(newValue);
|
||||
}
|
||||
|
||||
closeInlineCellAndResetEditModePosition();
|
||||
},
|
||||
closeInlineCellAndResetEditModePosition();
|
||||
},
|
||||
[
|
||||
closeInlineCellAndResetEditModePosition,
|
||||
instanceId,
|
||||
persistFieldFromFieldInputContext,
|
||||
store,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentTyp
|
||||
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { CustomError, isDefined } from 'twenty-shared/utils';
|
||||
import { IconCheck, IconPlus } from 'twenty-ui/display';
|
||||
import { LightIconButton } from 'twenty-ui/input';
|
||||
@@ -77,7 +77,7 @@ export const MultiItemFieldInput = <T,>({
|
||||
RecordFieldComponentInstanceContext,
|
||||
);
|
||||
|
||||
const currentFocusedItem = useRecoilValue(currentFocusedItemSelector);
|
||||
const currentFocusedItem = useRecoilValueV2(currentFocusedItemSelector);
|
||||
|
||||
useListenClickOutside({
|
||||
refs: [containerRef],
|
||||
|
||||
+8
-6
@@ -5,7 +5,6 @@ import { filesFieldUploadState } from '@/object-record/record-field/ui/states/fi
|
||||
import { filesFieldUploadStateV2 } from '@/object-record/record-field/ui/states/filesFieldUploadStateV2';
|
||||
import { type FieldFilesValue } from '@/object-record/record-field/ui/types/FieldMetadata';
|
||||
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { RECORD_TABLE_CELL_INPUT_ID_PREFIX } from '@/object-record/record-table/constants/RecordTableCellInputIdPrefix';
|
||||
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
|
||||
import { recordTableCellEditModePositionComponentState } from '@/object-record/record-table/states/recordTableCellEditModePositionComponentState';
|
||||
@@ -16,6 +15,7 @@ import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePush
|
||||
import { useRemoveLastFocusItemFromFocusStackByComponentType } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackByComponentType';
|
||||
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
||||
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
|
||||
import { useStore } from 'jotai';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { MULTI_ITEM_FIELD_DEFAULT_MAX_VALUES } from 'twenty-shared/constants';
|
||||
@@ -34,6 +34,7 @@ export const useOpenFilesFieldInput = () => {
|
||||
);
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
const { t } = useLingui();
|
||||
const store = useStore();
|
||||
|
||||
const openFilesFieldInput = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
@@ -101,7 +102,7 @@ export const useOpenFilesFieldInput = () => {
|
||||
filesFieldUploadState({ recordId, fieldName }),
|
||||
'UPLOAD_WINDOW_OPEN',
|
||||
);
|
||||
jotaiStore.set(
|
||||
store.set(
|
||||
filesFieldUploadStateV2.atomFamily({ recordId, fieldName }),
|
||||
'UPLOAD_WINDOW_OPEN',
|
||||
);
|
||||
@@ -115,7 +116,7 @@ export const useOpenFilesFieldInput = () => {
|
||||
});
|
||||
|
||||
set(filesFieldUploadState({ recordId, fieldName }), null);
|
||||
jotaiStore.set(
|
||||
store.set(
|
||||
filesFieldUploadStateV2.atomFamily({ recordId, fieldName }),
|
||||
null,
|
||||
);
|
||||
@@ -141,7 +142,7 @@ export const useOpenFilesFieldInput = () => {
|
||||
filesFieldUploadState({ recordId, fieldName }),
|
||||
'UPLOADING_FILE',
|
||||
);
|
||||
jotaiStore.set(
|
||||
store.set(
|
||||
filesFieldUploadStateV2.atomFamily({ recordId, fieldName }),
|
||||
'UPLOADING_FILE',
|
||||
);
|
||||
@@ -160,7 +161,7 @@ export const useOpenFilesFieldInput = () => {
|
||||
}
|
||||
} finally {
|
||||
set(filesFieldUploadState({ recordId, fieldName }), null);
|
||||
jotaiStore.set(
|
||||
store.set(
|
||||
filesFieldUploadStateV2.atomFamily({ recordId, fieldName }),
|
||||
null,
|
||||
);
|
||||
@@ -183,7 +184,7 @@ export const useOpenFilesFieldInput = () => {
|
||||
},
|
||||
onCancel: () => {
|
||||
set(filesFieldUploadState({ recordId, fieldName }), null);
|
||||
jotaiStore.set(
|
||||
store.set(
|
||||
filesFieldUploadStateV2.atomFamily({ recordId, fieldName }),
|
||||
null,
|
||||
);
|
||||
@@ -214,6 +215,7 @@ export const useOpenFilesFieldInput = () => {
|
||||
removeLastFocusItemFromFocusStackByComponentType,
|
||||
enqueueErrorSnackBar,
|
||||
t,
|
||||
store,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ import { RECORD_INDEX_REMOVE_SORTING_MODAL_ID } from '@/object-record/record-ind
|
||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||
import { RecordTableWithWrappers } from '@/object-record/record-table/components/RecordTableWithWrappers';
|
||||
import { isModalOpenedComponentState } from '@/ui/layout/modal/states/isModalOpenedComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
|
||||
type RecordIndexTableContainerProps = {
|
||||
recordTableId: string;
|
||||
@@ -17,7 +17,7 @@ export const RecordIndexTableContainer = ({
|
||||
const { objectNameSingular, viewBarInstanceId } =
|
||||
useRecordIndexContextOrThrow();
|
||||
|
||||
const isRecordIndexRemoveSortingModalOpened = useRecoilComponentValue(
|
||||
const isRecordIndexRemoveSortingModalOpened = useRecoilComponentValueV2(
|
||||
isModalOpenedComponentState,
|
||||
RECORD_INDEX_REMOVE_SORTING_MODAL_ID,
|
||||
);
|
||||
|
||||
+5
-2
@@ -15,7 +15,6 @@ import { recordIndexGroupAggregateFieldMetadataItemComponentState } from '@/obje
|
||||
import { recordIndexGroupAggregateOperationComponentState } from '@/object-record/record-index/states/recordIndexGroupAggregateOperationComponentState';
|
||||
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
|
||||
import { recordIndexOpenRecordInStateV2 } from '@/object-record/record-index/states/recordIndexOpenRecordInStateV2';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { recordIndexShouldHideEmptyRecordGroupsComponentState } from '@/object-record/record-index/states/recordIndexShouldHideEmptyRecordGroupsComponentState';
|
||||
import { recordIndexViewTypeState } from '@/object-record/record-index/states/recordIndexViewTypeState';
|
||||
import { viewFieldAggregateOperationState } from '@/object-record/record-table/record-table-footer/states/viewFieldAggregateOperationState';
|
||||
@@ -27,11 +26,14 @@ import { type View } from '@/views/types/View';
|
||||
import { type ViewField } from '@/views/types/ViewField';
|
||||
import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions';
|
||||
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
|
||||
import { useStore } from 'jotai';
|
||||
import { useRecoilCallback, useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
export const useLoadRecordIndexStates = () => {
|
||||
const store = useStore();
|
||||
|
||||
const setContextStoreTargetedRecordsRuleComponentState =
|
||||
useSetRecoilComponentState(contextStoreTargetedRecordsRuleComponentState);
|
||||
|
||||
@@ -203,7 +205,7 @@ export const useLoadRecordIndexStates = () => {
|
||||
|
||||
setRecordIndexViewType(view.type);
|
||||
setRecordIndexOpenRecordIn(view.openRecordIn);
|
||||
jotaiStore.set(recordIndexOpenRecordInStateV2.atom, view.openRecordIn);
|
||||
store.set(recordIndexOpenRecordInStateV2.atom, view.openRecordIn);
|
||||
|
||||
setRecordIndexCalendarFieldMetadataIdState(
|
||||
view.calendarFieldMetadataId ?? null,
|
||||
@@ -259,6 +261,7 @@ export const useLoadRecordIndexStates = () => {
|
||||
setRecordIndexGroupAggregateOperation,
|
||||
getFieldMetadataItemByIdOrThrow,
|
||||
setRecordIndexGroupFieldMetadataItem,
|
||||
store,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
+4
-4
@@ -19,7 +19,7 @@ import { usePersistFieldFromFieldInputContext } from '@/object-record/record-fie
|
||||
import { getDropdownFocusIdForRecordField } from '@/object-record/utils/getDropdownFocusIdForRecordField';
|
||||
import { useGoBackToPreviousDropdownFocusId } from '@/ui/layout/dropdown/hooks/useGoBackToPreviousDropdownFocusId';
|
||||
import { activeDropdownFocusIdState } from '@/ui/layout/dropdown/states/activeDropdownFocusIdState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { useStore } from 'jotai';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { RecordInlineCellContainer } from './RecordInlineCellContainer';
|
||||
import {
|
||||
@@ -46,6 +46,7 @@ export const RecordInlineCell = ({
|
||||
isRecordFieldReadOnly: isReadOnly,
|
||||
} = useContext(FieldContext);
|
||||
const { scopeInstanceId } = useRecordFieldsScopeContextOrThrow();
|
||||
const store = useStore();
|
||||
|
||||
const { openFieldInput, closeFieldInput } = useOpenFieldInputEditMode();
|
||||
|
||||
@@ -139,9 +140,7 @@ export const RecordInlineCell = ({
|
||||
newValue,
|
||||
skipPersist,
|
||||
}: Parameters<FieldInputClickOutsideEvent>[0]) => {
|
||||
const currentDropdownFocusId = jotaiStore.get(
|
||||
activeDropdownFocusIdState.atom,
|
||||
);
|
||||
const currentDropdownFocusId = store.get(activeDropdownFocusIdState.atom);
|
||||
|
||||
const expectedDropdownFocusId = getDropdownFocusIdForRecordField({
|
||||
recordId,
|
||||
@@ -169,6 +168,7 @@ export const RecordInlineCell = ({
|
||||
scopeInstanceId,
|
||||
closeInlineCell,
|
||||
persistFieldFromFieldInputContext,
|
||||
store,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ import { RightDrawerProvider } from '@/ui/layout/right-drawer/contexts/RightDraw
|
||||
import { TabList } from '@/ui/layout/tab-list/components/TabList';
|
||||
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
|
||||
import { TabListComponentInstanceContext } from '@/ui/layout/tab-list/states/contexts/TabListComponentInstanceContext';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
|
||||
import { CommandMenuPageComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuPageComponentInstanceContext';
|
||||
import { useMergeRecordsSelectedRecords } from '@/object-record/record-merge/hooks/useMergeRecordsSelectedRecords';
|
||||
@@ -52,7 +52,7 @@ export const MergeRecordsContainer = ({
|
||||
const instanceId = useAvailableComponentInstanceIdOrThrow(
|
||||
CommandMenuPageComponentInstanceContext,
|
||||
);
|
||||
const activeTabId = useRecoilComponentValue(
|
||||
const activeTabId = useRecoilComponentValueV2(
|
||||
activeTabIdComponentState,
|
||||
instanceId,
|
||||
);
|
||||
|
||||
+4
-3
@@ -8,10 +8,11 @@ import { multipleRecordPickerIsSelectedComponentFamilySelector } from '@/object-
|
||||
import { getMultipleRecordPickerSelectableListId } from '@/object-record/record-picker/multiple-record-picker/utils/getMultipleRecordPickerSelectableListId';
|
||||
import { type RecordPickerPickableMorphItem } from '@/object-record/record-picker/types/RecordPickerPickableMorphItem';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { isSelectedItemIdComponentFamilySelector } from '@/ui/layout/selectable-list/states/selectors/isSelectedItemIdComponentFamilySelector';
|
||||
import { isSelectedItemIdComponentFamilyState } from '@/ui/layout/selectable-list/states/isSelectedItemIdComponentFamilyState';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentFamilyValueV2';
|
||||
import { capitalize } from 'twenty-shared/utils';
|
||||
import { Avatar } from 'twenty-ui/display';
|
||||
import { MenuItemMultiSelectAvatar } from 'twenty-ui/navigation';
|
||||
@@ -42,8 +43,8 @@ export const MultipleRecordPickerMenuItemContent = ({
|
||||
const selectableListComponentInstanceId =
|
||||
getMultipleRecordPickerSelectableListId(componentInstanceId);
|
||||
|
||||
const isSelectedByKeyboard = useRecoilComponentFamilyValue(
|
||||
isSelectedItemIdComponentFamilySelector,
|
||||
const isSelectedByKeyboard = useRecoilComponentFamilyValueV2(
|
||||
isSelectedItemIdComponentFamilyState,
|
||||
searchRecord.recordId,
|
||||
selectableListComponentInstanceId,
|
||||
);
|
||||
|
||||
+4
-4
@@ -7,10 +7,10 @@ import { singleRecordPickerSearchableObjectMetadataItemsComponentState } from '@
|
||||
import { getSingleRecordPickerSelectableListId } from '@/object-record/record-picker/single-record-picker/utils/getSingleRecordPickerSelectableListId';
|
||||
import { type RecordPickerPickableMorphItem } from '@/object-record/record-picker/types/RecordPickerPickableMorphItem';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { isSelectedItemIdComponentFamilySelector } from '@/ui/layout/selectable-list/states/selectors/isSelectedItemIdComponentFamilySelector';
|
||||
import { isSelectedItemIdComponentFamilyState } from '@/ui/layout/selectable-list/states/isSelectedItemIdComponentFamilyState';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentFamilyValueV2';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { capitalize, isDefined } from 'twenty-shared/utils';
|
||||
import { Avatar } from 'twenty-ui/display';
|
||||
@@ -39,8 +39,8 @@ export const SingleRecordPickerMenuItem = ({
|
||||
const selectableListComponentInstanceId =
|
||||
getSingleRecordPickerSelectableListId(recordPickerComponentInstanceId);
|
||||
|
||||
const isSelectedByKeyboard = useRecoilComponentFamilyValue(
|
||||
isSelectedItemIdComponentFamilySelector,
|
||||
const isSelectedByKeyboard = useRecoilComponentFamilyValueV2(
|
||||
isSelectedItemIdComponentFamilyState,
|
||||
morphItem.recordId,
|
||||
selectableListComponentInstanceId,
|
||||
);
|
||||
|
||||
+4
-4
@@ -15,12 +15,12 @@ import { singleRecordPickerShouldShowSkeletonComponentState } from '@/object-rec
|
||||
import { getSingleRecordPickerSelectableListId } from '@/object-record/record-picker/single-record-picker/utils/getSingleRecordPickerSelectableListId';
|
||||
import { type RecordPickerPickableMorphItem } from '@/object-record/record-picker/types/RecordPickerPickableMorphItem';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { isSelectedItemIdComponentFamilySelector } from '@/ui/layout/selectable-list/states/selectors/isSelectedItemIdComponentFamilySelector';
|
||||
import { isSelectedItemIdComponentFamilyState } from '@/ui/layout/selectable-list/states/isSelectedItemIdComponentFamilyState';
|
||||
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentFamilyValueV2';
|
||||
import { type IconComponent } from 'twenty-ui/display';
|
||||
import { MenuItemSelect } from 'twenty-ui/navigation';
|
||||
|
||||
@@ -53,8 +53,8 @@ export const SingleRecordPickerMenuItems = ({
|
||||
selectableListComponentInstanceId,
|
||||
);
|
||||
|
||||
const isSelectedSelectNoneButton = useRecoilComponentFamilyValue(
|
||||
isSelectedItemIdComponentFamilySelector,
|
||||
const isSelectedSelectNoneButton = useRecoilComponentFamilyValueV2(
|
||||
isSelectedItemIdComponentFamilyState,
|
||||
selectableListComponentInstanceId,
|
||||
'select-none',
|
||||
);
|
||||
|
||||
+5
-6
@@ -5,7 +5,7 @@ import { buildFindOneRecordForShowPageOperationSignature } from '@/object-record
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { recordStoreFamilyStateV2 } from '@/object-record/record-store/states/recordStoreFamilyStateV2';
|
||||
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { useStore } from 'jotai';
|
||||
import { useEffect } from 'react';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
@@ -28,6 +28,8 @@ export const RecordShowEffect = ({
|
||||
objectMetadataItems,
|
||||
});
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const { record, loading } = useFindOneRecord({
|
||||
objectRecordId: recordId,
|
||||
objectNameSingular,
|
||||
@@ -44,13 +46,10 @@ export const RecordShowEffect = ({
|
||||
|
||||
if (JSON.stringify(previousRecordValue) !== JSON.stringify(newRecord)) {
|
||||
set(recordStoreFamilyState(recordId), newRecord);
|
||||
jotaiStore.set(
|
||||
recordStoreFamilyStateV2.atomFamily(recordId),
|
||||
newRecord,
|
||||
);
|
||||
store.set(recordStoreFamilyStateV2.atomFamily(recordId), newRecord);
|
||||
}
|
||||
},
|
||||
[recordId],
|
||||
[recordId, store],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
+6
-4
@@ -5,7 +5,7 @@ import { type RecordGqlFields } from '@/object-record/graphql/record-gql-fields/
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { recordStoreFamilyStateV2 } from '@/object-record/record-store/states/recordStoreFamilyStateV2';
|
||||
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { useStore } from 'jotai';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
@@ -15,6 +15,8 @@ type UpsertRecordsInStoreProps = {
|
||||
};
|
||||
|
||||
export const useUpsertRecordsInStore = () => {
|
||||
const store = useStore();
|
||||
|
||||
const upsertRecordsInStore = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
({ partialRecords, recordGqlFields }: UpsertRecordsInStoreProps) => {
|
||||
@@ -37,7 +39,7 @@ export const useUpsertRecordsInStore = () => {
|
||||
...filteredPartialRecord,
|
||||
};
|
||||
set(recordStoreFamilyState(partialRecord.id), newRecord);
|
||||
jotaiStore.set(
|
||||
store.set(
|
||||
recordStoreFamilyStateV2.atomFamily(partialRecord.id),
|
||||
newRecord,
|
||||
);
|
||||
@@ -57,14 +59,14 @@ export const useUpsertRecordsInStore = () => {
|
||||
...filteredPartialRecord,
|
||||
};
|
||||
set(recordStoreFamilyState(partialRecord.id), updatedRecord);
|
||||
jotaiStore.set(
|
||||
store.set(
|
||||
recordStoreFamilyStateV2.atomFamily(partialRecord.id),
|
||||
updatedRecord,
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
[],
|
||||
[store],
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
+4
-2
@@ -17,7 +17,7 @@ import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
|
||||
import { useRecoilComponentFamilyCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyCallbackState';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
import { useStore } from 'jotai';
|
||||
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
@@ -69,6 +69,7 @@ export const useSetRecordTableData = ({
|
||||
|
||||
const { unfocusRecordTableCell } = useUnfocusRecordTableCell(recordTableId);
|
||||
const { unfocusRecordTableRow } = useFocusedRecordTableRow(recordTableId);
|
||||
const store = useStore();
|
||||
|
||||
return useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
@@ -92,7 +93,7 @@ export const useSetRecordTableData = ({
|
||||
};
|
||||
|
||||
set(recordStoreFamilyState(record.id), newRecord);
|
||||
jotaiStore.set(
|
||||
store.set(
|
||||
recordStoreFamilyStateV2.atomFamily(record.id),
|
||||
newRecord,
|
||||
);
|
||||
@@ -162,6 +163,7 @@ export const useSetRecordTableData = ({
|
||||
isRowSelectedFamilyState,
|
||||
recordIdByRealIndexCallbackSelector,
|
||||
isRecordTableInitialLoadingCallbackState,
|
||||
store,
|
||||
],
|
||||
);
|
||||
};
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@ import { PAGE_ACTION_CONTAINER_CLICK_OUTSIDE_ID } from '@/ui/layout/page/constan
|
||||
import { currentFocusedItemSelector } from '@/ui/utilities/focus/states/currentFocusedItemSelector';
|
||||
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
|
||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
type RecordTableBodyFocusClickOutsideEffectProps = {
|
||||
tableBodyRef: React.RefObject<HTMLDivElement>;
|
||||
};
|
||||
@@ -20,7 +20,7 @@ export const RecordTableBodyFocusClickOutsideEffect = ({
|
||||
|
||||
const leaveTableFocus = useLeaveTableFocus(recordTableId);
|
||||
|
||||
const currentFocusedItem = useRecoilValue(currentFocusedItemSelector);
|
||||
const currentFocusedItem = useRecoilValueV2(currentFocusedItemSelector);
|
||||
|
||||
const componentType = currentFocusedItem?.componentInstance.componentType;
|
||||
|
||||
|
||||
+17
-18
@@ -11,10 +11,12 @@ import {
|
||||
import { useRecordTableBodyContextOrThrow } from '@/object-record/record-table/contexts/RecordTableBodyContext';
|
||||
import { currentFocusIdSelector } from '@/ui/utilities/focus/states/currentFocusIdSelector';
|
||||
import { useAvailableComponentInstanceId } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceId';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const RecordTableCellFieldInput = () => {
|
||||
const { onMoveFocus, onCloseTableCell } = useRecordTableBodyContextOrThrow();
|
||||
const store = useStore();
|
||||
|
||||
const instanceId = useAvailableComponentInstanceId(
|
||||
RecordFieldComponentInstanceContext,
|
||||
@@ -44,26 +46,23 @@ export const RecordTableCellFieldInput = () => {
|
||||
onCloseTableCell();
|
||||
};
|
||||
|
||||
const handleClickOutside: FieldInputClickOutsideEvent = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
({ newValue, event, skipPersist }) => {
|
||||
const currentFocusId = snapshot
|
||||
.getLoadable(currentFocusIdSelector)
|
||||
.getValue();
|
||||
const handleClickOutside: FieldInputClickOutsideEvent = useCallback(
|
||||
({ newValue, event, skipPersist }) => {
|
||||
const currentFocusId = store.get(currentFocusIdSelector.atom);
|
||||
|
||||
if (currentFocusId !== instanceId) {
|
||||
return;
|
||||
}
|
||||
event?.preventDefault();
|
||||
event?.stopImmediatePropagation();
|
||||
if (currentFocusId !== instanceId) {
|
||||
return;
|
||||
}
|
||||
event?.preventDefault();
|
||||
event?.stopImmediatePropagation();
|
||||
|
||||
if (skipPersist !== true) {
|
||||
persistFieldFromFieldInputContext(newValue);
|
||||
}
|
||||
if (skipPersist !== true) {
|
||||
persistFieldFromFieldInputContext(newValue);
|
||||
}
|
||||
|
||||
onCloseTableCell();
|
||||
},
|
||||
[onCloseTableCell, instanceId, persistFieldFromFieldInputContext],
|
||||
onCloseTableCell();
|
||||
},
|
||||
[onCloseTableCell, instanceId, persistFieldFromFieldInputContext, store],
|
||||
);
|
||||
|
||||
const handleEscape: FieldInputEvent = ({ newValue, skipPersist }) => {
|
||||
|
||||
+19
-23
@@ -1,5 +1,3 @@
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { FOCUS_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-table/constants/FocusClickOutsideListenerId';
|
||||
import { RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-table/constants/RecordTableClickOutsideListenerId';
|
||||
import { useDragSelect } from '@/ui/utilities/drag-select/hooks/useDragSelect';
|
||||
@@ -8,10 +6,12 @@ import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useC
|
||||
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||
import { useCloseCurrentTableCellInEditMode } from '@/object-record/record-table/hooks/internal/useCloseCurrentTableCellInEditMode';
|
||||
import { clickOutsideListenerIsActivatedComponentState } from '@/ui/utilities/pointer-event/states/clickOutsideListenerIsActivatedComponentState';
|
||||
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const useCloseRecordTableCellInGroup = () => {
|
||||
const { recordTableId } = useRecordTableContextOrThrow();
|
||||
const store = useStore();
|
||||
|
||||
const { setDragSelectionStartEnabled } = useDragSelect();
|
||||
|
||||
@@ -22,26 +22,22 @@ export const useCloseRecordTableCellInGroup = () => {
|
||||
const closeCurrentTableCellInEditMode =
|
||||
useCloseCurrentTableCellInEditMode(recordTableId);
|
||||
|
||||
const clickOutsideListenerIsActivatedState = useRecoilComponentCallbackState(
|
||||
clickOutsideListenerIsActivatedComponentState,
|
||||
RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID,
|
||||
);
|
||||
|
||||
const closeTableCellInGroup = useRecoilCallback(
|
||||
({ set }) =>
|
||||
() => {
|
||||
toggleClickOutside(true);
|
||||
setDragSelectionStartEnabled(true);
|
||||
closeCurrentTableCellInEditMode();
|
||||
set(clickOutsideListenerIsActivatedState, true);
|
||||
},
|
||||
[
|
||||
clickOutsideListenerIsActivatedState,
|
||||
closeCurrentTableCellInEditMode,
|
||||
setDragSelectionStartEnabled,
|
||||
toggleClickOutside,
|
||||
],
|
||||
);
|
||||
const closeTableCellInGroup = useCallback(() => {
|
||||
toggleClickOutside(true);
|
||||
setDragSelectionStartEnabled(true);
|
||||
closeCurrentTableCellInEditMode();
|
||||
store.set(
|
||||
clickOutsideListenerIsActivatedComponentState.atomFamily({
|
||||
instanceId: RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID,
|
||||
}),
|
||||
true,
|
||||
);
|
||||
}, [
|
||||
closeCurrentTableCellInEditMode,
|
||||
setDragSelectionStartEnabled,
|
||||
toggleClickOutside,
|
||||
store,
|
||||
]);
|
||||
|
||||
return {
|
||||
closeTableCellInGroup,
|
||||
|
||||
+19
-22
@@ -6,11 +6,12 @@ import { RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-t
|
||||
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||
import { useCloseCurrentTableCellInEditMode } from '@/object-record/record-table/hooks/internal/useCloseCurrentTableCellInEditMode';
|
||||
import { clickOutsideListenerIsActivatedComponentState } from '@/ui/utilities/pointer-event/states/clickOutsideListenerIsActivatedComponentState';
|
||||
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const useCloseRecordTableCellNoGroup = () => {
|
||||
const { recordTableId } = useRecordTableContextOrThrow();
|
||||
const store = useStore();
|
||||
|
||||
const { setDragSelectionStartEnabled } = useDragSelect();
|
||||
|
||||
@@ -21,26 +22,22 @@ export const useCloseRecordTableCellNoGroup = () => {
|
||||
const closeCurrentTableCellInEditMode =
|
||||
useCloseCurrentTableCellInEditMode(recordTableId);
|
||||
|
||||
const clickOutsideListenerIsActivatedState = useRecoilComponentCallbackState(
|
||||
clickOutsideListenerIsActivatedComponentState,
|
||||
RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID,
|
||||
);
|
||||
|
||||
const closeTableCellNoGroup = useRecoilCallback(
|
||||
({ set }) =>
|
||||
() => {
|
||||
toggleClickOutside(true);
|
||||
setDragSelectionStartEnabled(true);
|
||||
closeCurrentTableCellInEditMode();
|
||||
set(clickOutsideListenerIsActivatedState, true);
|
||||
},
|
||||
[
|
||||
clickOutsideListenerIsActivatedState,
|
||||
closeCurrentTableCellInEditMode,
|
||||
setDragSelectionStartEnabled,
|
||||
toggleClickOutside,
|
||||
],
|
||||
);
|
||||
const closeTableCellNoGroup = useCallback(() => {
|
||||
toggleClickOutside(true);
|
||||
setDragSelectionStartEnabled(true);
|
||||
closeCurrentTableCellInEditMode();
|
||||
store.set(
|
||||
clickOutsideListenerIsActivatedComponentState.atomFamily({
|
||||
instanceId: RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID,
|
||||
}),
|
||||
true,
|
||||
);
|
||||
}, [
|
||||
closeCurrentTableCellInEditMode,
|
||||
setDragSelectionStartEnabled,
|
||||
toggleClickOutside,
|
||||
store,
|
||||
]);
|
||||
|
||||
return {
|
||||
closeTableCellNoGroup,
|
||||
|
||||
+10
-8
@@ -28,8 +28,8 @@ import { useFocusedRecordTableRow } from '@/object-record/record-table/hooks/use
|
||||
import { useFocusRecordTableCell } from '@/object-record/record-table/record-table-cell/hooks/useFocusRecordTableCell';
|
||||
import { isRecordTableRowFocusActiveComponentState } from '@/object-record/record-table/states/isRecordTableRowFocusActiveComponentState';
|
||||
import { clickOutsideListenerIsActivatedComponentState } from '@/ui/utilities/pointer-event/states/clickOutsideListenerIsActivatedComponentState';
|
||||
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import { useStore } from 'jotai';
|
||||
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
|
||||
|
||||
export type OpenTableCellArgs = {
|
||||
@@ -43,11 +43,8 @@ export type OpenTableCellArgs = {
|
||||
|
||||
export const useOpenRecordTableCell = (recordTableId: string) => {
|
||||
const { scopeInstanceId } = useRecordFieldsScopeContextOrThrow();
|
||||
const store = useStore();
|
||||
|
||||
const clickOutsideListenerIsActivatedState = useRecoilComponentCallbackState(
|
||||
clickOutsideListenerIsActivatedComponentState,
|
||||
RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID,
|
||||
);
|
||||
const setCurrentTableCellInEditModePosition = useSetRecoilComponentState(
|
||||
recordTableCellEditModePositionComponentState,
|
||||
recordTableId,
|
||||
@@ -82,7 +79,7 @@ export const useOpenRecordTableCell = (recordTableId: string) => {
|
||||
const { openRecordFromIndexView } = useOpenRecordFromIndexView();
|
||||
|
||||
const openTableCell = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
({ snapshot }) =>
|
||||
({
|
||||
initialValue,
|
||||
cellPosition,
|
||||
@@ -91,7 +88,12 @@ export const useOpenRecordTableCell = (recordTableId: string) => {
|
||||
recordId,
|
||||
isNavigating,
|
||||
}: OpenTableCellArgs) => {
|
||||
set(clickOutsideListenerIsActivatedState, false);
|
||||
store.set(
|
||||
clickOutsideListenerIsActivatedComponentState.atomFamily({
|
||||
instanceId: RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID,
|
||||
}),
|
||||
false,
|
||||
);
|
||||
|
||||
const isFirstColumnCell = cellPosition.column === 0;
|
||||
|
||||
@@ -169,7 +171,6 @@ export const useOpenRecordTableCell = (recordTableId: string) => {
|
||||
);
|
||||
},
|
||||
[
|
||||
clickOutsideListenerIsActivatedState,
|
||||
deactivateRecordTableRow,
|
||||
focusRecordTableCell,
|
||||
setIsRowFocusActive,
|
||||
@@ -184,6 +185,7 @@ export const useOpenRecordTableCell = (recordTableId: string) => {
|
||||
openRecordFromIndexView,
|
||||
activateRecordTableRow,
|
||||
unfocusRecordTableRow,
|
||||
store,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ import { SelectableListItem } from '@/ui/layout/selectable-list/components/Selec
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilComponentValueV2';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { Avatar } from 'twenty-ui/display';
|
||||
import { MenuItem, MenuItemMultiSelectAvatar } from 'twenty-ui/navigation';
|
||||
@@ -39,7 +39,7 @@ export const MultipleSelectDropdown = ({
|
||||
|
||||
const { resetSelectedItem } = useSelectableList(selectableListId);
|
||||
|
||||
const selectedItemId = useRecoilComponentValue(
|
||||
const selectedItemId = useRecoilComponentValueV2(
|
||||
selectedItemIdComponentState,
|
||||
selectableListId,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user