3157 refactor scoped states to move to v3 (#3180)
* renaming * renaming * create getDropdownScopeInjectors * update useDropdown * create internal hooks folder * update record-table states to be scoped states * update record-table selectors to be scoped selectors * create utils scope injector * refactor record-table wip * refactor record-table wip * wip * inject scopeId in selectors * update intenal hooks * update intenal hooks * update intenal hooks * update intenal hooks * update intenal hooks * update intenal hooks * update internal hooks * update internal hooks * update internal hooks * update internal hooks * update useTableColumns * update states and hooks * refactoring * refactoring * refactoring * refactoring * refactoring * refactoring * refactoring * refactoring * refactoring * fix scopeId not in context * fix lint errors * fix error in story * fix errors: wip * fix errors * fix error * fix jest test * fix scopeId not defined * fix jest test * Bug fixes --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -95,7 +95,7 @@ export const IconPicker = ({
|
||||
setHotkeyScopeAndMemorizePreviousScope,
|
||||
} = usePreviousHotkeyScope();
|
||||
|
||||
const { closeDropdown } = useDropdown({ dropdownScopeId });
|
||||
const { closeDropdown } = useDropdown(dropdownScopeId);
|
||||
|
||||
const { getIcons, getIcon } = useIcons();
|
||||
const icons = getIcons();
|
||||
|
||||
@ -74,7 +74,7 @@ export const Select = <Value extends string | number | null>({
|
||||
const selectedOption =
|
||||
options.find(({ value: key }) => key === value) || options[0];
|
||||
|
||||
const { closeDropdown } = useDropdown({ dropdownScopeId });
|
||||
const { closeDropdown } = useDropdown(dropdownScopeId);
|
||||
|
||||
const selectControl = (
|
||||
<StyledControlContainer disabled={disabled} fullWidth={fullWidth}>
|
||||
|
||||
@ -75,9 +75,7 @@ export const CountryPickerDropdownButton = ({
|
||||
|
||||
const [selectedCountry, setSelectedCountry] = useState<Country>();
|
||||
|
||||
const { isDropdownOpen, closeDropdown } = useDropdown({
|
||||
dropdownScopeId: 'country-picker',
|
||||
});
|
||||
const { isDropdownOpen, closeDropdown } = useDropdown('country-picker');
|
||||
|
||||
const handleChange = (countryCode: string) => {
|
||||
onChange(countryCode);
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
import { DropdownScopeInternalContext } from '@/ui/layout/dropdown/scopes/scope-internal-context/DropdownScopeInternalContext';
|
||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||
import { useScopedState } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useScopedState';
|
||||
|
||||
type UseDropdownScopedStatesProps = {
|
||||
dropdownScopeId?: string;
|
||||
};
|
||||
|
||||
export const useDropdownScopedStates = ({
|
||||
dropdownScopeId,
|
||||
}: UseDropdownScopedStatesProps) => {
|
||||
const scopeId = useAvailableScopeIdOrThrow(
|
||||
DropdownScopeInternalContext,
|
||||
dropdownScopeId,
|
||||
);
|
||||
|
||||
const {
|
||||
getScopedState,
|
||||
getScopedFamilyState,
|
||||
getScopedSnapshotValue,
|
||||
getScopedFamilySnapshotValue,
|
||||
} = useScopedState(scopeId);
|
||||
|
||||
return {
|
||||
scopeId,
|
||||
injectStateWithDropdownScopeId: getScopedState,
|
||||
injectFamilyStateWithDropdownScopeId: getScopedFamilyState,
|
||||
injectSnapshotValueWithDropdownScopeId: getScopedSnapshotValue,
|
||||
injectFamilySnapshotValueWithDropdownScopeId: getScopedFamilySnapshotValue,
|
||||
};
|
||||
};
|
||||
@ -1,44 +1,44 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { useDropdownScopedStates } from '@/ui/layout/dropdown/hooks/internal/useDropdownScopedStates';
|
||||
import { getDropdownScopeInjectors } from '@/ui/layout/dropdown/utils/internal/getDropdownScopeInjectors';
|
||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||
|
||||
import { DropdownScopeInternalContext } from '../scopes/scope-internal-context/DropdownScopeInternalContext';
|
||||
export const useDropdown = (dropdownId?: string) => {
|
||||
const { injectStateWithDropdownScopeId, scopeId } = useDropdownScopedStates({
|
||||
dropdownScopeId: dropdownId,
|
||||
});
|
||||
|
||||
import { useDropdownStates } from './useDropdownStates';
|
||||
const {
|
||||
dropdownHotkeyScopeScopeInjector,
|
||||
dropdownWidthScopeInjector,
|
||||
isDropdownOpenScopeInjector,
|
||||
} = getDropdownScopeInjectors();
|
||||
|
||||
type UseDropdownProps = {
|
||||
dropdownScopeId?: string;
|
||||
};
|
||||
|
||||
export const useDropdown = (props?: UseDropdownProps) => {
|
||||
const {
|
||||
setHotkeyScopeAndMemorizePreviousScope,
|
||||
goBackToPreviousHotkeyScope,
|
||||
} = usePreviousHotkeyScope();
|
||||
|
||||
const scopeId = useAvailableScopeIdOrThrow(
|
||||
DropdownScopeInternalContext,
|
||||
props?.dropdownScopeId,
|
||||
const [dropdownHotkeyScope, setDropdownHotkeyScope] = useRecoilState(
|
||||
injectStateWithDropdownScopeId(dropdownHotkeyScopeScopeInjector),
|
||||
);
|
||||
|
||||
const {
|
||||
dropdownHotkeyScope,
|
||||
setDropdownHotkeyScope,
|
||||
isDropdownOpen,
|
||||
setIsDropdownOpen,
|
||||
dropdownWidth,
|
||||
setDropdownWidth,
|
||||
} = useDropdownStates({
|
||||
scopeId,
|
||||
});
|
||||
const [dropdownWidth, setDropdownWidth] = useRecoilState(
|
||||
injectStateWithDropdownScopeId(dropdownWidthScopeInjector),
|
||||
);
|
||||
|
||||
const closeDropdownButton = () => {
|
||||
const [isDropdownOpen, setIsDropdownOpen] = useRecoilState(
|
||||
injectStateWithDropdownScopeId(isDropdownOpenScopeInjector),
|
||||
);
|
||||
|
||||
const closeDropdown = () => {
|
||||
goBackToPreviousHotkeyScope();
|
||||
setIsDropdownOpen(false);
|
||||
};
|
||||
|
||||
const openDropdownButton = () => {
|
||||
const openDropdown = () => {
|
||||
setIsDropdownOpen(true);
|
||||
|
||||
if (dropdownHotkeyScope) {
|
||||
setHotkeyScopeAndMemorizePreviousScope(
|
||||
dropdownHotkeyScope.scope,
|
||||
@ -47,20 +47,20 @@ export const useDropdown = (props?: UseDropdownProps) => {
|
||||
}
|
||||
};
|
||||
|
||||
const toggleDropdownButton = () => {
|
||||
const toggleDropdown = () => {
|
||||
if (isDropdownOpen) {
|
||||
closeDropdownButton();
|
||||
closeDropdown();
|
||||
} else {
|
||||
openDropdownButton();
|
||||
openDropdown();
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
scopeId,
|
||||
isDropdownOpen: isDropdownOpen,
|
||||
closeDropdown: closeDropdownButton,
|
||||
toggleDropdown: toggleDropdownButton,
|
||||
openDropdown: openDropdownButton,
|
||||
closeDropdown,
|
||||
toggleDropdown,
|
||||
openDropdown,
|
||||
dropdownHotkeyScope,
|
||||
setDropdownHotkeyScope,
|
||||
dropdownWidth,
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
import { useRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedStateV2';
|
||||
|
||||
import { dropdownHotkeyScopeScopedState } from '../states/dropdownHotkeyScopeScopedState';
|
||||
import { dropdownWidthScopedState } from '../states/dropdownWidthScopedState';
|
||||
import { isDropdownOpenScopedState } from '../states/isDropdownOpenScopedState';
|
||||
|
||||
export const useDropdownStates = ({ scopeId }: { scopeId: string }) => {
|
||||
const [isDropdownOpen, setIsDropdownOpen] = useRecoilScopedStateV2(
|
||||
isDropdownOpenScopedState,
|
||||
scopeId,
|
||||
);
|
||||
|
||||
const [dropdownHotkeyScope, setDropdownHotkeyScope] = useRecoilScopedStateV2(
|
||||
dropdownHotkeyScopeScopedState,
|
||||
scopeId,
|
||||
);
|
||||
|
||||
const [dropdownWidth, setDropdownWidth] = useRecoilScopedStateV2(
|
||||
dropdownWidthScopedState,
|
||||
scopeId,
|
||||
);
|
||||
|
||||
return {
|
||||
isDropdownOpen,
|
||||
setIsDropdownOpen,
|
||||
dropdownHotkeyScope,
|
||||
setDropdownHotkeyScope,
|
||||
dropdownWidth,
|
||||
setDropdownWidth,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,22 @@
|
||||
import { dropdownHotkeyScopeScopedState } from '@/ui/layout/dropdown/states/dropdownHotkeyScopeScopedState';
|
||||
import { dropdownWidthScopedState } from '@/ui/layout/dropdown/states/dropdownWidthScopedState';
|
||||
import { isDropdownOpenScopedState } from '@/ui/layout/dropdown/states/isDropdownOpenScopedState';
|
||||
import { getScopeInjector } from '@/ui/utilities/recoil-scope/utils/getScopeInjector';
|
||||
|
||||
export const getDropdownScopeInjectors = () => {
|
||||
const dropdownHotkeyScopeScopeInjector = getScopeInjector(
|
||||
dropdownHotkeyScopeScopedState,
|
||||
);
|
||||
|
||||
const dropdownWidthScopeInjector = getScopeInjector(dropdownWidthScopedState);
|
||||
|
||||
const isDropdownOpenScopeInjector = getScopeInjector(
|
||||
isDropdownOpenScopedState,
|
||||
);
|
||||
|
||||
return {
|
||||
dropdownHotkeyScopeScopeInjector,
|
||||
dropdownWidthScopeInjector,
|
||||
isDropdownOpenScopeInjector,
|
||||
};
|
||||
};
|
||||
@ -27,11 +27,10 @@ export const useSelectableListHotKeys = (
|
||||
}
|
||||
};
|
||||
|
||||
const { getSelectableListScopedSnapshotValue } = useSelectableListScopedState(
|
||||
{
|
||||
const { injectSnapshotValueWithSelectableListScopeId } =
|
||||
useSelectableListScopedState({
|
||||
selectableListScopeId: scopeId,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
const handleSelect = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
@ -42,11 +41,11 @@ export const useSelectableListHotKeys = (
|
||||
isSelectedItemIdFamilyScopeInjector,
|
||||
} = getSelectableListScopeInjectors();
|
||||
|
||||
const selectedItemId = getSelectableListScopedSnapshotValue(
|
||||
const selectedItemId = injectSnapshotValueWithSelectableListScopeId(
|
||||
snapshot,
|
||||
selectedItemIdScopeInjector,
|
||||
);
|
||||
const selectableItemIds = getSelectableListScopedSnapshotValue(
|
||||
const selectableItemIds = injectSnapshotValueWithSelectableListScopeId(
|
||||
snapshot,
|
||||
selectableItemIdsScopeInjector,
|
||||
);
|
||||
@ -120,7 +119,7 @@ export const useSelectableListHotKeys = (
|
||||
}
|
||||
}
|
||||
},
|
||||
[getSelectableListScopedSnapshotValue, scopeId],
|
||||
[injectSnapshotValueWithSelectableListScopeId, scopeId],
|
||||
);
|
||||
|
||||
useScopedHotkeys(Key.ArrowUp, () => handleSelect('up'), hotkeyScope, []);
|
||||
@ -145,12 +144,12 @@ export const useSelectableListHotKeys = (
|
||||
selectedItemIdScopeInjector,
|
||||
selectableListOnEnterScopeInjector,
|
||||
} = getSelectableListScopeInjectors();
|
||||
const selectedItemId = getSelectableListScopedSnapshotValue(
|
||||
const selectedItemId = injectSnapshotValueWithSelectableListScopeId(
|
||||
snapshot,
|
||||
selectedItemIdScopeInjector,
|
||||
);
|
||||
|
||||
const onEnter = getSelectableListScopedSnapshotValue(
|
||||
const onEnter = injectSnapshotValueWithSelectableListScopeId(
|
||||
snapshot,
|
||||
selectableListOnEnterScopeInjector,
|
||||
);
|
||||
@ -159,7 +158,7 @@ export const useSelectableListHotKeys = (
|
||||
onEnter?.(selectedItemId);
|
||||
}
|
||||
},
|
||||
[getSelectableListScopedSnapshotValue],
|
||||
[injectSnapshotValueWithSelectableListScopeId],
|
||||
),
|
||||
hotkeyScope,
|
||||
[],
|
||||
|
||||
@ -23,9 +23,10 @@ export const useSelectableListScopedState = ({
|
||||
|
||||
return {
|
||||
scopeId,
|
||||
getSelectableListScopedState: getScopedState,
|
||||
getSelectableListScopedFamilyState: getScopedFamilyState,
|
||||
getSelectableListScopedSnapshotValue: getScopedSnapshotValue,
|
||||
getSelectableListScopedFamilySnapshotValue: getScopedFamilySnapshotValue,
|
||||
injectStateWithSelectableListScopeId: getScopedState,
|
||||
injectFamilyStateWithSelectableListScopeId: getScopedFamilyState,
|
||||
injectSnapshotValueWithSelectableListScopeId: getScopedSnapshotValue,
|
||||
injectFamilySnapshotValueWithSelectableListScopeId:
|
||||
getScopedFamilySnapshotValue,
|
||||
};
|
||||
};
|
||||
|
||||
@ -3,13 +3,13 @@ import { useResetRecoilState, useSetRecoilState } from 'recoil';
|
||||
import { useSelectableListScopedState } from '@/ui/layout/selectable-list/hooks/internal/useSelectableListScopedState';
|
||||
import { getSelectableListScopeInjectors } from '@/ui/layout/selectable-list/utils/internal/getSelectableListScopeInjectors';
|
||||
|
||||
export const useSelectableList = (selectableListScopeId?: string) => {
|
||||
export const useSelectableList = (selectableListId?: string) => {
|
||||
const {
|
||||
getSelectableListScopedState,
|
||||
getSelectableListScopedFamilyState,
|
||||
injectStateWithSelectableListScopeId,
|
||||
injectFamilyStateWithSelectableListScopeId,
|
||||
scopeId,
|
||||
} = useSelectableListScopedState({
|
||||
selectableListScopeId,
|
||||
selectableListScopeId: selectableListId,
|
||||
});
|
||||
|
||||
const {
|
||||
@ -20,17 +20,18 @@ export const useSelectableList = (selectableListScopeId?: string) => {
|
||||
} = getSelectableListScopeInjectors();
|
||||
|
||||
const setSelectableItemIds = useSetRecoilState(
|
||||
getSelectableListScopedState(selectableItemIdsScopeInjector),
|
||||
injectStateWithSelectableListScopeId(selectableItemIdsScopeInjector),
|
||||
);
|
||||
const setSelectableListOnEnter = useSetRecoilState(
|
||||
getSelectableListScopedState(selectableListOnEnterScopeInjector),
|
||||
);
|
||||
const isSelectedItemIdFamilyState = getSelectableListScopedFamilyState(
|
||||
isSelectedItemIdFamilyScopeInjector,
|
||||
injectStateWithSelectableListScopeId(selectableListOnEnterScopeInjector),
|
||||
);
|
||||
const isSelectedItemIdFamilyState =
|
||||
injectFamilyStateWithSelectableListScopeId(
|
||||
isSelectedItemIdFamilyScopeInjector,
|
||||
);
|
||||
|
||||
const resetSelectedItemIdState = useResetRecoilState(
|
||||
getSelectableListScopedState(selectedItemIdScopeInjector),
|
||||
injectStateWithSelectableListScopeId(selectedItemIdScopeInjector),
|
||||
);
|
||||
|
||||
const resetSelectedItem = () => {
|
||||
|
||||
@ -23,9 +23,7 @@ export const ShowPageAddButton = ({
|
||||
}: {
|
||||
entity: ActivityTargetableEntity;
|
||||
}) => {
|
||||
const { closeDropdown, toggleDropdown } = useDropdown({
|
||||
dropdownScopeId: 'add-show-page',
|
||||
});
|
||||
const { closeDropdown, toggleDropdown } = useDropdown('add-show-page');
|
||||
const openCreateActivity = useOpenCreateActivityDrawer();
|
||||
|
||||
const handleSelect = (type: ActivityType) => {
|
||||
|
||||
@ -26,9 +26,7 @@ export const ShowPageMoreButton = ({
|
||||
recordId: string;
|
||||
objectNameSingular: string;
|
||||
}) => {
|
||||
const { closeDropdown, toggleDropdown } = useDropdown({
|
||||
dropdownScopeId: 'more-show-page',
|
||||
});
|
||||
const { closeDropdown, toggleDropdown } = useDropdown('more-show-page');
|
||||
const navigationMemorizedUrl = useRecoilValue(navigationMemorizedUrlState);
|
||||
const navigate = useNavigate();
|
||||
|
||||
|
||||
@ -67,10 +67,6 @@ export const useSetHotkeyScope = () =>
|
||||
scopesToSet.push(AppHotkeyScope.CommandMenu);
|
||||
}
|
||||
|
||||
if (newHotkeyScope.customScopes?.commandMenuOpen) {
|
||||
scopesToSet.push(AppHotkeyScope.CommandMenuOpen);
|
||||
}
|
||||
|
||||
if (newHotkeyScope?.customScopes?.goto) {
|
||||
scopesToSet.push(AppHotkeyScope.Goto);
|
||||
}
|
||||
|
||||
@ -2,12 +2,17 @@ import { SerializableParam, Snapshot } from 'recoil';
|
||||
|
||||
import { FamilyScopeInjector } from '@/ui/utilities/recoil-scope/utils/getFamilyScopeInjector';
|
||||
import { ScopeInjector } from '@/ui/utilities/recoil-scope/utils/getScopeInjector';
|
||||
import { SelectorScopeInjector } from '@/ui/utilities/recoil-scope/utils/getSelectorScopeInjector';
|
||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
||||
|
||||
export const useScopedState = (scopeId: string) => {
|
||||
const getScopedState = <StateType>(scopeInjector: ScopeInjector<StateType>) =>
|
||||
scopeInjector(scopeId);
|
||||
|
||||
const getScopedSelector = <StateType>(
|
||||
scopeInjector: SelectorScopeInjector<StateType>,
|
||||
) => scopeInjector(scopeId);
|
||||
|
||||
const getScopedFamilyState =
|
||||
<StateType, FamilyKey extends SerializableParam>(
|
||||
familyScopeInjector: FamilyScopeInjector<StateType, FamilyKey>,
|
||||
@ -16,23 +21,30 @@ export const useScopedState = (scopeId: string) => {
|
||||
familyScopeInjector(scopeId, familyKey);
|
||||
|
||||
const getScopedSnapshotValue = <StateType>(
|
||||
snashot: Snapshot,
|
||||
snapshot: Snapshot,
|
||||
scopeInjector: ScopeInjector<StateType>,
|
||||
) => getSnapshotValue(snashot, scopeInjector(scopeId));
|
||||
) => getSnapshotValue(snapshot, scopeInjector(scopeId));
|
||||
|
||||
const getScopedSelectorSnapshotValue = <StateType>(
|
||||
snapshot: Snapshot,
|
||||
scopeInjector: SelectorScopeInjector<StateType>,
|
||||
) => getSnapshotValue(snapshot, scopeInjector(scopeId));
|
||||
|
||||
const getScopedFamilySnapshotValue =
|
||||
<StateType, FamilyKey extends SerializableParam>(
|
||||
snashot: Snapshot,
|
||||
snapshot: Snapshot,
|
||||
familyScopeInjector: FamilyScopeInjector<StateType, FamilyKey>,
|
||||
) =>
|
||||
(familyKey: FamilyKey) =>
|
||||
getSnapshotValue(snashot, familyScopeInjector(scopeId, familyKey));
|
||||
getSnapshotValue(snapshot, familyScopeInjector(scopeId, familyKey));
|
||||
|
||||
return {
|
||||
scopeId,
|
||||
getScopedState,
|
||||
getScopedSelector,
|
||||
getScopedFamilyState,
|
||||
getScopedSnapshotValue,
|
||||
getScopedSelectorSnapshotValue,
|
||||
getScopedFamilySnapshotValue,
|
||||
};
|
||||
};
|
||||
|
||||
@ -8,7 +8,7 @@ export type ScopeInjector<StateType> = (
|
||||
|
||||
export const getScopeInjector = <StateType>(
|
||||
scopedState: RecoilScopedState<StateType>,
|
||||
) => {
|
||||
): ScopeInjector<StateType> => {
|
||||
return (scopeId: string) =>
|
||||
scopedState({
|
||||
scopeId,
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
import { RecoilValueReadOnly } from 'recoil';
|
||||
|
||||
import { RecoilScopedSelector } from '@/ui/utilities/recoil-scope/types/RecoilScopedSelector';
|
||||
|
||||
export type SelectorScopeInjector<StateType> = (
|
||||
scopeId: string,
|
||||
) => RecoilValueReadOnly<StateType>;
|
||||
|
||||
export const getSelectorScopeInjector = <StateType>(
|
||||
scopedSelector: RecoilScopedSelector<StateType>,
|
||||
): SelectorScopeInjector<StateType> => {
|
||||
return (scopeId: string) =>
|
||||
scopedSelector({
|
||||
scopeId,
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user