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:
bosiraphael
2024-01-03 19:45:14 +01:00
committed by GitHub
parent 65250839fb
commit b0d3e6d8d3
112 changed files with 1447 additions and 716 deletions

View File

@ -20,7 +20,7 @@ export const AttachmentDropdown = ({
}: AttachmentDropdownProps) => { }: AttachmentDropdownProps) => {
const dropdownScopeId = `${scopeKey}-settings-field-active-action-dropdown`; const dropdownScopeId = `${scopeKey}-settings-field-active-action-dropdown`;
const { closeDropdown } = useDropdown({ dropdownScopeId }); const { closeDropdown } = useDropdown(dropdownScopeId);
const handleDownload = () => { const handleDownload = () => {
onDownload(); onDownload();

View File

@ -1,7 +1,8 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { ActivityType } from '@/activities/types/Activity'; import { ActivityType } from '@/activities/types/Activity';
import { selectedRowIdsSelector } from '@/object-record/record-table/states/selectors/selectedRowIdsSelector'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { import {
ActivityTargetableEntity, ActivityTargetableEntity,
@ -10,9 +11,16 @@ import {
import { useOpenCreateActivityDrawer } from './useOpenCreateActivityDrawer'; import { useOpenCreateActivityDrawer } from './useOpenCreateActivityDrawer';
export const useOpenCreateActivityDrawerForSelectedRowIds = () => { export const useOpenCreateActivityDrawerForSelectedRowIds = (
recordTableScopeId: string,
) => {
const openCreateActivityDrawer = useOpenCreateActivityDrawer(); const openCreateActivityDrawer = useOpenCreateActivityDrawer();
const { selectedRowIdsScopeInjector } = getRecordTableScopeInjector();
const { injectSelectorSnapshotValueWithRecordTableScopeId } =
useRecordTableScopedStates(recordTableScopeId);
return useRecoilCallback( return useRecoilCallback(
({ snapshot }) => ({ snapshot }) =>
( (
@ -20,9 +28,12 @@ export const useOpenCreateActivityDrawerForSelectedRowIds = () => {
entityType: ActivityTargetableEntityType, entityType: ActivityTargetableEntityType,
relatedEntities?: ActivityTargetableEntity[], relatedEntities?: ActivityTargetableEntity[],
) => { ) => {
const selectedRowIds = snapshot const selectedRowIds =
.getLoadable(selectedRowIdsSelector) injectSelectorSnapshotValueWithRecordTableScopeId(
.getValue(); snapshot,
selectedRowIdsScopeInjector,
);
let activityTargetableEntityArray: ActivityTargetableEntity[] = let activityTargetableEntityArray: ActivityTargetableEntity[] =
selectedRowIds.map((id: string) => ({ selectedRowIds.map((id: string) => ({
type: entityType, type: entityType,
@ -37,6 +48,10 @@ export const useOpenCreateActivityDrawerForSelectedRowIds = () => {
targetableEntities: activityTargetableEntityArray, targetableEntities: activityTargetableEntityArray,
}); });
}, },
[openCreateActivityDrawer], [
injectSelectorSnapshotValueWithRecordTableScopeId,
openCreateActivityDrawer,
selectedRowIdsScopeInjector,
],
); );
}; };

View File

@ -13,10 +13,10 @@ describe('groupActivitiesByMonth', () => {
expect(grouped[0].items).toHaveLength(1); expect(grouped[0].items).toHaveLength(1);
expect(grouped[1].items).toHaveLength(1); expect(grouped[1].items).toHaveLength(1);
expect(grouped[0].year).toBe(2023); expect(grouped[0].year).toBe(new Date().getFullYear());
expect(grouped[1].year).toBe(2023); expect(grouped[1].year).toBe(2023);
expect(grouped[0].month).toBe(11); expect(grouped[0].month).toBe(new Date().getMonth());
expect(grouped[1].month).toBe(3); expect(grouped[1].month).toBe(3);
}); });
}); });

View File

@ -23,7 +23,7 @@ export const useCommandMenu = () => {
const openCommandMenu = () => { const openCommandMenu = () => {
setIsCommandMenuOpened(true); setIsCommandMenuOpened(true);
setHotkeyScopeAndMemorizePreviousScope(AppHotkeyScope.CommandMenu); setHotkeyScopeAndMemorizePreviousScope(AppHotkeyScope.CommandMenuOpen);
}; };
const closeCommandMenu = () => { const closeCommandMenu = () => {

View File

@ -28,9 +28,11 @@ const StyledContainer = styled.div`
`; `;
export const RecordTableContainer = ({ export const RecordTableContainer = ({
recordTableId,
objectNamePlural, objectNamePlural,
createRecord, createRecord,
}: { }: {
recordTableId: string;
objectNamePlural: string; objectNamePlural: string;
createRecord: () => void; createRecord: () => void;
}) => { }) => {
@ -52,7 +54,6 @@ export const RecordTableContainer = ({
const { openPersonSpreadsheetImport } = useSpreadsheetPersonImport(); const { openPersonSpreadsheetImport } = useSpreadsheetPersonImport();
const { openCompanySpreadsheetImport } = useSpreadsheetCompanyImport(); const { openCompanySpreadsheetImport } = useSpreadsheetCompanyImport();
const recordTableId = objectNamePlural ?? '';
const viewBarId = objectNamePlural ?? ''; const viewBarId = objectNamePlural ?? '';
const { setTableFilters, setTableSorts, setTableColumns } = useRecordTable({ const { setTableFilters, setTableSorts, setTableColumns } = useRecordTable({

View File

@ -61,6 +61,8 @@ export const RecordTablePage = () => {
await createOneObject?.({}); await createOneObject?.({});
}; };
const recordTableId = objectNamePlural ?? '';
return ( return (
<PageContainer> <PageContainer>
<PageHeader <PageHeader
@ -75,12 +77,13 @@ export const RecordTablePage = () => {
<PageBody> <PageBody>
<StyledTableContainer> <StyledTableContainer>
<RecordTableContainer <RecordTableContainer
recordTableId={recordTableId}
objectNamePlural={objectNamePlural} objectNamePlural={objectNamePlural}
createRecord={handleAddButtonClick} createRecord={handleAddButtonClick}
/> />
</StyledTableContainer> </StyledTableContainer>
<RecordTableActionBar /> <RecordTableActionBar recordTableId={recordTableId} />
<RecordTableContextMenu /> <RecordTableContextMenu recordTableId={recordTableId} />
</PageBody> </PageBody>
</PageContainer> </PageContainer>
); );

View File

@ -7,13 +7,17 @@ import { turnSortsIntoOrderBy } from '@/object-record/object-sort-dropdown/utils
import { turnObjectDropdownFilterIntoQueryFilter } from '@/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter'; import { turnObjectDropdownFilterIntoQueryFilter } from '@/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { isRecordTableInitialLoadingState } from '@/object-record/record-table/states/isRecordTableInitialLoadingState'; import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { signInBackgroundMockCompanies } from '@/sign-in-background-mock/constants/signInBackgroundMockCompanies'; import { signInBackgroundMockCompanies } from '@/sign-in-background-mock/constants/signInBackgroundMockCompanies';
import { useFindManyRecords } from './useFindManyRecords'; import { useFindManyRecords } from './useFindManyRecords';
export const useObjectRecordTable = () => { export const useObjectRecordTable = () => {
const { scopeId: objectNamePlural, setRecordTableData } = useRecordTable(); const {
scopeId: objectNamePlural,
setRecordTableData,
setIsRecordTableInitialLoading,
} = useRecordTable();
const currentWorkspace = useRecoilValue(currentWorkspaceState); const currentWorkspace = useRecoilValue(currentWorkspaceState);
const { objectNameSingular } = useObjectNameSingularFromPlural({ const { objectNameSingular } = useObjectNameSingularFromPlural({
@ -25,8 +29,26 @@ export const useObjectRecordTable = () => {
objectNameSingular, objectNameSingular,
}, },
); );
const { tableFiltersState, tableSortsState, tableLastRowVisibleState } =
useRecordTableScopedStates(); const {
tableFiltersScopeInjector,
tableSortsScopeInjector,
tableLastRowVisibleScopeInjector,
} = getRecordTableScopeInjector();
const { injectStateWithRecordTableScopeId } = useRecordTableScopedStates();
const tableFiltersState = injectStateWithRecordTableScopeId(
tableFiltersScopeInjector,
);
const tableSortsState = injectStateWithRecordTableScopeId(
tableSortsScopeInjector,
);
const tableLastRowVisibleState = injectStateWithRecordTableScopeId(
tableLastRowVisibleScopeInjector,
);
const tableFilters = useRecoilValue(tableFiltersState); const tableFilters = useRecoilValue(tableFiltersState);
const tableSorts = useRecoilValue(tableSortsState); const tableSorts = useRecoilValue(tableSortsState);
@ -42,10 +64,6 @@ export const useObjectRecordTable = () => {
foundObjectMetadataItem?.fields ?? [], foundObjectMetadataItem?.fields ?? [],
); );
const setIsRecordTableInitialLoading = useSetRecoilState(
isRecordTableInitialLoadingState,
);
const { records, loading, fetchMoreRecords, queryStateIdentifier } = const { records, loading, fetchMoreRecords, queryStateIdentifier } =
useFindManyRecords({ useFindManyRecords({
objectNameSingular, objectNameSingular,

View File

@ -8,9 +8,10 @@ import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObje
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState'; import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState';
import { useDeleteManyRecords } from '@/object-record/hooks/useDeleteManyRecords'; import { useDeleteManyRecords } from '@/object-record/hooks/useDeleteManyRecords';
import { useExecuteQuickActionOnOneRecord } from '@/object-record/hooks/useExecuteQuickActionOnOneRecord'; import { useExecuteQuickActionOnOneRecord } from '@/object-record/hooks/useExecuteQuickActionOnOneRecord';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { RecordTableScopeInternalContext } from '@/object-record/record-table/scopes/scope-internal-context/RecordTableScopeInternalContext'; import { RecordTableScopeInternalContext } from '@/object-record/record-table/scopes/scope-internal-context/RecordTableScopeInternalContext';
import { selectedRowIdsSelector } from '@/object-record/record-table/states/selectors/selectedRowIdsSelector'; import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { import {
IconCheckbox, IconCheckbox,
IconHeart, IconHeart,
@ -41,12 +42,25 @@ export const useRecordTableContextMenuEntries = (
const setContextMenuEntries = useSetRecoilState(contextMenuEntriesState); const setContextMenuEntries = useSetRecoilState(contextMenuEntriesState);
const setActionBarEntriesState = useSetRecoilState(actionBarEntriesState); const setActionBarEntriesState = useSetRecoilState(actionBarEntriesState);
const { selectedRowIdsScopeInjector } = getRecordTableScopeInjector();
const {
injectSelectorWithRecordTableScopeId,
injectSelectorSnapshotValueWithRecordTableScopeId,
} = useRecordTableScopedStates(scopeId);
const selectedRowIdsSelector = injectSelectorWithRecordTableScopeId(
selectedRowIdsScopeInjector,
);
const selectedRowIds = useRecoilValue(selectedRowIdsSelector); const selectedRowIds = useRecoilValue(selectedRowIdsSelector);
const { scopeId: objectNamePlural, resetTableRowSelection } = useRecordTable({ const { resetTableRowSelection } = useRecordTable({
recordTableScopeId: scopeId, recordTableScopeId: scopeId,
}); });
const objectNamePlural = scopeId;
const { objectNameSingular } = useObjectNameSingularFromPlural({ const { objectNameSingular } = useObjectNameSingularFromPlural({
objectNamePlural, objectNamePlural,
}); });
@ -61,9 +75,10 @@ export const useRecordTableContextMenuEntries = (
: 'Custom'; : 'Custom';
const handleFavoriteButtonClick = useRecoilCallback(({ snapshot }) => () => { const handleFavoriteButtonClick = useRecoilCallback(({ snapshot }) => () => {
const selectedRowIds = snapshot const selectedRowIds = injectSelectorSnapshotValueWithRecordTableScopeId(
.getLoadable(selectedRowIdsSelector) snapshot,
.getValue(); selectedRowIdsScopeInjector,
);
const selectedRowId = selectedRowIds.length === 1 ? selectedRowIds[0] : ''; const selectedRowId = selectedRowIds.length === 1 ? selectedRowIds[0] : '';
@ -97,22 +112,31 @@ export const useRecordTableContextMenuEntries = (
const handleDeleteClick = useRecoilCallback( const handleDeleteClick = useRecoilCallback(
({ snapshot }) => ({ snapshot }) =>
async () => { async () => {
const rowIdsToDelete = snapshot const rowIdsToDelete =
.getLoadable(selectedRowIdsSelector) injectSelectorSnapshotValueWithRecordTableScopeId(
.getValue(); snapshot,
selectedRowIdsScopeInjector,
);
resetTableRowSelection(); resetTableRowSelection();
await deleteManyRecords(rowIdsToDelete); await deleteManyRecords(rowIdsToDelete);
}, },
[deleteManyRecords, resetTableRowSelection], [
deleteManyRecords,
injectSelectorSnapshotValueWithRecordTableScopeId,
resetTableRowSelection,
selectedRowIdsScopeInjector,
],
); );
const handleExecuteQuickActionOnClick = useRecoilCallback( const handleExecuteQuickActionOnClick = useRecoilCallback(
({ snapshot }) => ({ snapshot }) =>
async () => { async () => {
const rowIdsToExecuteQuickActionOn = snapshot const rowIdsToExecuteQuickActionOn =
.getLoadable(selectedRowIdsSelector) injectSelectorSnapshotValueWithRecordTableScopeId(
.getValue(); snapshot,
selectedRowIdsScopeInjector,
);
resetTableRowSelection(); resetTableRowSelection();
await Promise.all( await Promise.all(
@ -121,7 +145,12 @@ export const useRecordTableContextMenuEntries = (
}), }),
); );
}, },
[executeQuickActionOnOneRecord, resetTableRowSelection], [
executeQuickActionOnOneRecord,
injectSelectorSnapshotValueWithRecordTableScopeId,
resetTableRowSelection,
selectedRowIdsScopeInjector,
],
); );
const dataExecuteQuickActionOnmentEnabled = useIsFeatureEnabled( const dataExecuteQuickActionOnmentEnabled = useIsFeatureEnabled(
@ -129,7 +158,7 @@ export const useRecordTableContextMenuEntries = (
); );
const openCreateActivityDrawer = const openCreateActivityDrawer =
useOpenCreateActivityDrawerForSelectedRowIds(); useOpenCreateActivityDrawerForSelectedRowIds(scopeId);
return { return {
setContextMenuEntries: useCallback(() => { setContextMenuEntries: useCallback(() => {

View File

@ -12,9 +12,7 @@ type AddObjectFilterFromDetailsButtonProps = {
export const AddObjectFilterFromDetailsButton = ({ export const AddObjectFilterFromDetailsButton = ({
filterDropdownId, filterDropdownId,
}: AddObjectFilterFromDetailsButtonProps) => { }: AddObjectFilterFromDetailsButtonProps) => {
const { toggleDropdown } = useDropdown({ const { toggleDropdown } = useDropdown(ObjectFilterDropdownId);
dropdownScopeId: ObjectFilterDropdownId,
});
const { resetFilter } = useFilterDropdown({ const { resetFilter } = useFilterDropdown({
filterDropdownId: filterDropdownId, filterDropdownId: filterDropdownId,

View File

@ -7,9 +7,9 @@ import { ObjectFilterDropdownId } from '../constants/ObjectFilterDropdownId';
export const MultipleFiltersButton = () => { export const MultipleFiltersButton = () => {
const { resetFilter } = useFilterDropdown(); const { resetFilter } = useFilterDropdown();
const { isDropdownOpen, toggleDropdown } = useDropdown({ const { isDropdownOpen, toggleDropdown } = useDropdown(
dropdownScopeId: ObjectFilterDropdownId, ObjectFilterDropdownId,
}); );
const handleClick = () => { const handleClick = () => {
toggleDropdown(); toggleDropdown();

View File

@ -42,9 +42,7 @@ export const ObjectSortDropdownButton = ({
sortDropdownId: sortDropdownId, sortDropdownId: sortDropdownId,
}); });
const { toggleDropdown } = useDropdown({ const { toggleDropdown } = useDropdown(ObjectSortDropdownId);
dropdownScopeId: ObjectSortDropdownId,
});
const handleButtonClick = () => { const handleButtonClick = () => {
toggleDropdown(); toggleDropdown();

View File

@ -1,11 +1,23 @@
import React from 'react';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { ActionBar } from '@/ui/navigation/action-bar/components/ActionBar'; import { ActionBar } from '@/ui/navigation/action-bar/components/ActionBar';
import { selectedRowIdsSelector } from '../../states/selectors/selectedRowIdsSelector'; export const RecordTableActionBar = ({
recordTableId,
}: {
recordTableId: string;
}) => {
const { selectedRowIdsScopeInjector } = getRecordTableScopeInjector();
const { injectSelectorWithRecordTableScopeId } =
useRecordTableScopedStates(recordTableId);
const selectedRowIdsSelector = injectSelectorWithRecordTableScopeId(
selectedRowIdsScopeInjector,
);
export const RecordTableActionBar = () => {
const selectedRowIds = useRecoilValue(selectedRowIdsSelector); const selectedRowIds = useRecoilValue(selectedRowIdsSelector);
return <ActionBar selectedIds={selectedRowIds} />; return <ActionBar selectedIds={selectedRowIds} />;

View File

@ -4,9 +4,18 @@ import { RecordTableBodyFetchMoreLoader } from '@/object-record/record-table/com
import { RecordTableRow } from '@/object-record/record-table/components/RecordTableRow'; import { RecordTableRow } from '@/object-record/record-table/components/RecordTableRow';
import { RowIdContext } from '@/object-record/record-table/contexts/RowIdContext'; import { RowIdContext } from '@/object-record/record-table/contexts/RowIdContext';
import { RowIndexContext } from '@/object-record/record-table/contexts/RowIndexContext'; import { RowIndexContext } from '@/object-record/record-table/contexts/RowIndexContext';
import { tableRowIdsState } from '@/object-record/record-table/states/tableRowIdsState'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
export const RecordTableBody = () => { export const RecordTableBody = () => {
const { tableRowIdsScopeInjector } = getRecordTableScopeInjector();
const { injectStateWithRecordTableScopeId } = useRecordTableScopedStates();
const tableRowIdsState = injectStateWithRecordTableScopeId(
tableRowIdsScopeInjector,
);
const tableRowIds = useRecoilValue(tableRowIdsState); const tableRowIds = useRecoilValue(tableRowIdsState);
return ( return (

View File

@ -3,6 +3,7 @@ import { useRecoilState, useRecoilValue } from 'recoil';
import { useObjectRecordTable } from '@/object-record/hooks/useObjectRecordTable'; import { useObjectRecordTable } from '@/object-record/hooks/useObjectRecordTable';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { isFetchingMoreRecordsFamilyState } from '@/object-record/states/isFetchingMoreRecordsFamilyState'; import { isFetchingMoreRecordsFamilyState } from '@/object-record/states/isFetchingMoreRecordsFamilyState';
export const RecordTableBodyEffect = () => { export const RecordTableBodyEffect = () => {
@ -13,7 +14,15 @@ export const RecordTableBodyEffect = () => {
queryStateIdentifier, queryStateIdentifier,
loading, loading,
} = useObjectRecordTable(); } = useObjectRecordTable();
const { tableLastRowVisibleState } = useRecordTableScopedStates();
const { tableLastRowVisibleScopeInjector } = getRecordTableScopeInjector();
const { injectStateWithRecordTableScopeId } = useRecordTableScopedStates();
const tableLastRowVisibleState = injectStateWithRecordTableScopeId(
tableLastRowVisibleScopeInjector,
);
const [tableLastRowVisible, setTableLastRowVisible] = useRecoilState( const [tableLastRowVisible, setTableLastRowVisible] = useRecoilState(
tableLastRowVisibleState, tableLastRowVisibleState,
); );

View File

@ -4,26 +4,21 @@ import { useRecoilCallback, useRecoilValue } from 'recoil';
import { useObjectRecordTable } from '@/object-record/hooks/useObjectRecordTable'; import { useObjectRecordTable } from '@/object-record/hooks/useObjectRecordTable';
import { StyledRow } from '@/object-record/record-table/components/RecordTableRow'; import { StyledRow } from '@/object-record/record-table/components/RecordTableRow';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { getRecordTableScopedStates } from '@/object-record/record-table/utils/getRecordTableScopedStates';
import { isFetchingMoreRecordsFamilyState } from '@/object-record/states/isFetchingMoreRecordsFamilyState'; import { isFetchingMoreRecordsFamilyState } from '@/object-record/states/isFetchingMoreRecordsFamilyState';
export const RecordTableBodyFetchMoreLoader = () => { export const RecordTableBodyFetchMoreLoader = () => {
const { queryStateIdentifier } = useObjectRecordTable(); const { queryStateIdentifier } = useObjectRecordTable();
const { scopeId } = useRecordTable(); const { setRecordTableLastRowVisible } = useRecordTable();
const isFetchingMoreObjects = useRecoilValue( const isFetchingMoreObjects = useRecoilValue(
isFetchingMoreRecordsFamilyState(queryStateIdentifier), isFetchingMoreRecordsFamilyState(queryStateIdentifier),
); );
const onLastRowVisible = useRecoilCallback( const onLastRowVisible = useRecoilCallback(
({ set }) => () => async (inView: boolean) => {
async (inView: boolean) => { setRecordTableLastRowVisible(inView);
const { tableLastRowVisibleState } = getRecordTableScopedStates({ },
recordTableScopeId: scopeId, [setRecordTableLastRowVisible],
});
set(tableLastRowVisibleState, inView);
},
[scopeId],
); );
const { ref: tbodyRef } = useInView({ const { ref: tbodyRef } = useInView({

View File

@ -2,6 +2,7 @@ import { useContext } from 'react';
import { useRecoilValue, useSetRecoilState } from 'recoil'; import { useRecoilValue, useSetRecoilState } from 'recoil';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope'; import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState'; import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState';
import { contextMenuPositionState } from '@/ui/navigation/context-menu/states/contextMenuPositionState'; import { contextMenuPositionState } from '@/ui/navigation/context-menu/states/contextMenuPositionState';
@ -13,17 +14,25 @@ import { ColumnContext } from '../contexts/ColumnContext';
import { ColumnIndexContext } from '../contexts/ColumnIndexContext'; import { ColumnIndexContext } from '../contexts/ColumnIndexContext';
import { RecordUpdateContext } from '../contexts/EntityUpdateMutationHookContext'; import { RecordUpdateContext } from '../contexts/EntityUpdateMutationHookContext';
import { RowIdContext } from '../contexts/RowIdContext'; import { RowIdContext } from '../contexts/RowIdContext';
import { TableCell } from '../record-table-cell/components/RecordTableCell'; import { RecordTableCell } from '../record-table-cell/components/RecordTableCell';
import { useCurrentRowSelected } from '../record-table-row/hooks/useCurrentRowSelected'; import { useCurrentRowSelected } from '../record-table-row/hooks/useCurrentRowSelected';
import { TableHotkeyScope } from '../types/TableHotkeyScope'; import { TableHotkeyScope } from '../types/TableHotkeyScope';
export const RecordTableCell = ({ cellIndex }: { cellIndex: number }) => { export const RecordTableCellContainer = ({
cellIndex,
}: {
cellIndex: number;
}) => {
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState); const setContextMenuPosition = useSetRecoilState(contextMenuPositionState);
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState); const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState);
const currentRowId = useContext(RowIdContext); const currentRowId = useContext(RowIdContext);
const { objectMetadataConfigState } = useRecordTableScopedStates(); const { objectMetadataConfigScopeInjector } = getRecordTableScopeInjector();
const objectMetadataConfig = useRecoilValue(objectMetadataConfigState); const { injectStateWithRecordTableScopeId } = useRecordTableScopedStates();
const objectMetadataConfig = useRecoilValue(
injectStateWithRecordTableScopeId(objectMetadataConfigScopeInjector),
);
const { setCurrentRowSelected } = useCurrentRowSelected(); const { setCurrentRowSelected } = useCurrentRowSelected();
@ -66,7 +75,7 @@ export const RecordTableCell = ({ cellIndex }: { cellIndex: number }) => {
objectMetadataConfig?.labelIdentifierFieldMetadataId, objectMetadataConfig?.labelIdentifierFieldMetadataId,
}} }}
> >
<TableCell customHotkeyScope={{ scope: customHotkeyScope }} /> <RecordTableCell customHotkeyScope={{ scope: customHotkeyScope }} />
</FieldContext.Provider> </FieldContext.Provider>
</td> </td>
</ColumnIndexContext.Provider> </ColumnIndexContext.Provider>

View File

@ -3,6 +3,7 @@ import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { RecordTableHeaderCell } from '@/object-record/record-table/components/RecordTableHeaderCell'; import { RecordTableHeaderCell } from '@/object-record/record-table/components/RecordTableHeaderCell';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { IconPlus } from '@/ui/display/icon'; import { IconPlus } from '@/ui/display/icon';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope'; import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
@ -58,8 +59,18 @@ export const RecordTableHeader = ({
}: { }: {
createRecord: () => void; createRecord: () => void;
}) => { }) => {
const { hiddenTableColumnsSelector, visibleTableColumnsSelector } = const { hiddenTableColumnsScopeInjector, visibleTableColumnsScopeInjector } =
useRecordTableScopedStates(); getRecordTableScopeInjector();
const { injectSelectorWithRecordTableScopeId } = useRecordTableScopedStates();
const hiddenTableColumnsSelector = injectSelectorWithRecordTableScopeId(
hiddenTableColumnsScopeInjector,
);
const visibleTableColumnsSelector = injectSelectorWithRecordTableScopeId(
visibleTableColumnsScopeInjector,
);
const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector); const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector);

View File

@ -5,8 +5,8 @@ import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata'; import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { useTableColumns } from '@/object-record/record-table/hooks/useTableColumns'; import { useTableColumns } from '@/object-record/record-table/hooks/useTableColumns';
import { resizeFieldOffsetState } from '@/object-record/record-table/states/resizeFieldOffsetState';
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition'; import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { IconPlus } from '@/ui/display/icon'; import { IconPlus } from '@/ui/display/icon';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton'; import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { useTrackPointer } from '@/ui/utilities/pointer-event/hooks/useTrackPointer'; import { useTrackPointer } from '@/ui/utilities/pointer-event/hooks/useTrackPointer';
@ -80,15 +80,38 @@ export const RecordTableHeaderCell = ({
column: ColumnDefinition<FieldMetadata>; column: ColumnDefinition<FieldMetadata>;
createRecord: () => void; createRecord: () => void;
}) => { }) => {
const {
resizeFieldOffsetScopeInjector,
tableColumnsScopeInjector,
tableColumnsByKeyScopeInjector,
visibleTableColumnsScopeInjector,
} = getRecordTableScopeInjector();
const {
injectStateWithRecordTableScopeId,
injectSelectorWithRecordTableScopeId,
injectSnapshotValueWithRecordTableScopeId,
} = useRecordTableScopedStates();
const resizeFieldOffsetState = injectStateWithRecordTableScopeId(
resizeFieldOffsetScopeInjector,
);
const [resizeFieldOffset, setResizeFieldOffset] = useRecoilState( const [resizeFieldOffset, setResizeFieldOffset] = useRecoilState(
resizeFieldOffsetState, resizeFieldOffsetState,
); );
const { const tableColumnsState = injectStateWithRecordTableScopeId(
tableColumnsState, tableColumnsScopeInjector,
tableColumnsByKeySelector, );
visibleTableColumnsSelector,
} = useRecordTableScopedStates(); const tableColumnsByKeySelector = injectSelectorWithRecordTableScopeId(
tableColumnsByKeyScopeInjector,
);
const visibleTableColumnsSelector = injectSelectorWithRecordTableScopeId(
visibleTableColumnsScopeInjector,
);
const tableColumns = useRecoilValue(tableColumnsState); const tableColumns = useRecoilValue(tableColumnsState);
const tableColumnsByKey = useRecoilValue(tableColumnsByKeySelector); const tableColumnsByKey = useRecoilValue(tableColumnsByKeySelector);
@ -124,10 +147,14 @@ export const RecordTableHeaderCell = ({
async () => { async () => {
if (!resizedFieldKey) return; if (!resizedFieldKey) return;
const resizeFieldOffset = injectSnapshotValueWithRecordTableScopeId(
snapshot,
resizeFieldOffsetScopeInjector,
);
const nextWidth = Math.round( const nextWidth = Math.round(
Math.max( Math.max(
tableColumnsByKey[resizedFieldKey].size + tableColumnsByKey[resizedFieldKey].size + resizeFieldOffset,
snapshot.getLoadable(resizeFieldOffsetState).valueOrThrow(),
COLUMN_MIN_WIDTH, COLUMN_MIN_WIDTH,
), ),
); );
@ -146,7 +173,15 @@ export const RecordTableHeaderCell = ({
await handleColumnsChange(nextColumns); await handleColumnsChange(nextColumns);
} }
}, },
[resizedFieldKey, tableColumnsByKey, tableColumns, handleColumnsChange], [
resizedFieldKey,
injectSnapshotValueWithRecordTableScopeId,
resizeFieldOffsetScopeInjector,
tableColumnsByKey,
resizeFieldOffsetState,
tableColumns,
handleColumnsChange,
],
); );
useTrackPointer({ useTrackPointer({

View File

@ -3,6 +3,7 @@ import { Link } from 'react-router-dom';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { IconSettings } from '@/ui/display/icon'; import { IconSettings } from '@/ui/display/icon';
import { useIcons } from '@/ui/display/icon/hooks/useIcons'; import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
@ -18,7 +19,13 @@ import { ColumnDefinition } from '../types/ColumnDefinition';
export const RecordTableHeaderPlusButtonContent = () => { export const RecordTableHeaderPlusButtonContent = () => {
const { closeDropdown } = useDropdown(); const { closeDropdown } = useDropdown();
const { hiddenTableColumnsSelector } = useRecordTableScopedStates(); const { hiddenTableColumnsScopeInjector } = getRecordTableScopeInjector();
const { injectSelectorWithRecordTableScopeId } = useRecordTableScopedStates();
const hiddenTableColumnsSelector = injectSelectorWithRecordTableScopeId(
hiddenTableColumnsScopeInjector,
);
const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector); const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector);

View File

@ -3,6 +3,8 @@ import { useInView } from 'react-intersection-observer';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { RecordTableCellContainer } from '@/object-record/record-table/components/RecordTableCellContainer';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { ScrollWrapperContext } from '@/ui/utilities/scroll/components/ScrollWrapper'; import { ScrollWrapperContext } from '@/ui/utilities/scroll/components/ScrollWrapper';
import { ColumnContext } from '../contexts/ColumnContext'; import { ColumnContext } from '../contexts/ColumnContext';
@ -10,7 +12,6 @@ import { useRecordTableScopedStates } from '../hooks/internal/useRecordTableScop
import { useCurrentRowSelected } from '../record-table-row/hooks/useCurrentRowSelected'; import { useCurrentRowSelected } from '../record-table-row/hooks/useCurrentRowSelected';
import { CheckboxCell } from './CheckboxCell'; import { CheckboxCell } from './CheckboxCell';
import { RecordTableCell } from './RecordTableCell';
export const StyledRow = styled.tr<{ selected: boolean }>` export const StyledRow = styled.tr<{ selected: boolean }>`
background: ${(props) => background: ${(props) =>
@ -26,7 +27,13 @@ const StyledPlaceholder = styled.td`
`; `;
export const RecordTableRow = ({ rowId }: RecordTableRowProps) => { export const RecordTableRow = ({ rowId }: RecordTableRowProps) => {
const { visibleTableColumnsSelector } = useRecordTableScopedStates(); const { visibleTableColumnsScopeInjector } = getRecordTableScopeInjector();
const { injectSelectorWithRecordTableScopeId } = useRecordTableScopedStates();
const visibleTableColumnsSelector = injectSelectorWithRecordTableScopeId(
visibleTableColumnsScopeInjector,
);
const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector); const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector);
@ -59,7 +66,7 @@ export const RecordTableRow = ({ rowId }: RecordTableRowProps) => {
value={column} value={column}
key={column.fieldMetadataId} key={column.fieldMetadataId}
> >
<RecordTableCell cellIndex={columnIndex} /> <RecordTableCellContainer cellIndex={columnIndex} />
</ColumnContext.Provider> </ColumnContext.Provider>
); );
})} })}

View File

@ -7,7 +7,8 @@ import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObje
import { RecordTable } from '@/object-record/record-table/components/RecordTable'; import { RecordTable } from '@/object-record/record-table/components/RecordTable';
import { RecordTableFirstColumnScrollObserver } from '@/object-record/record-table/components/RecordTableFirstColumnScrollObserver'; import { RecordTableFirstColumnScrollObserver } from '@/object-record/record-table/components/RecordTableFirstColumnScrollObserver';
import { RecordTableRefContextWrapper } from '@/object-record/record-table/components/RecordTableRefContext'; import { RecordTableRefContextWrapper } from '@/object-record/record-table/components/RecordTableRefContext';
import { isRecordTableInitialLoadingState } from '@/object-record/record-table/states/isRecordTableInitialLoadingState'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { IconPlus } from '@/ui/display/icon'; import { IconPlus } from '@/ui/display/icon';
import { Button } from '@/ui/input/button/components/Button'; import { Button } from '@/ui/input/button/components/Button';
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect'; import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
@ -18,7 +19,6 @@ import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinit
import { RecordUpdateContext } from '../contexts/EntityUpdateMutationHookContext'; import { RecordUpdateContext } from '../contexts/EntityUpdateMutationHookContext';
import { useRecordTable } from '../hooks/useRecordTable'; import { useRecordTable } from '../hooks/useRecordTable';
import { RecordTableScope } from '../scopes/RecordTableScope'; import { RecordTableScope } from '../scopes/RecordTableScope';
import { numberOfTableRowsState } from '../states/numberOfTableRowsState';
import { RecordTableInternalEffect } from './RecordTableInternalEffect'; import { RecordTableInternalEffect } from './RecordTableInternalEffect';
@ -80,6 +80,22 @@ export const RecordTableWithWrappers = ({
}: RecordTableWithWrappersProps) => { }: RecordTableWithWrappersProps) => {
const tableBodyRef = useRef<HTMLDivElement>(null); const tableBodyRef = useRef<HTMLDivElement>(null);
const {
numberOfTableRowsScopeInjector,
isRecordTableInitialLoadingScopeInjector,
} = getRecordTableScopeInjector();
const { injectStateWithRecordTableScopeId } =
useRecordTableScopedStates(recordTableId);
const numberOfTableRowsState = injectStateWithRecordTableScopeId(
numberOfTableRowsScopeInjector,
);
const isRecordTableInitialLoadingState = injectStateWithRecordTableScopeId(
isRecordTableInitialLoadingScopeInjector,
);
const numberOfTableRows = useRecoilValue(numberOfTableRowsState); const numberOfTableRows = useRecoilValue(numberOfTableRowsState);
const isRecordTableInitialLoading = useRecoilValue( const isRecordTableInitialLoading = useRecoilValue(

View File

@ -1,10 +1,11 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { Checkbox } from '@/ui/input/components/Checkbox'; import { Checkbox } from '@/ui/input/components/Checkbox';
import { useRecordTable } from '../hooks/useRecordTable'; import { useRecordTable } from '../hooks/useRecordTable';
import { allRowsSelectedStatusSelector } from '../states/selectors/allRowsSelectedStatusSelector';
const StyledContainer = styled.div` const StyledContainer = styled.div`
align-items: center; align-items: center;
@ -16,7 +17,16 @@ const StyledContainer = styled.div`
`; `;
export const SelectAllCheckbox = () => { export const SelectAllCheckbox = () => {
const allRowsSelectedStatus = useRecoilValue(allRowsSelectedStatusSelector); const { allRowsSelectedStatusScopeInjector } = getRecordTableScopeInjector();
const { injectSelectorWithRecordTableScopeId } = useRecordTableScopedStates();
const allRowsSelectedStatusScopedSelector =
injectSelectorWithRecordTableScopeId(allRowsSelectedStatusScopeInjector);
const allRowsSelectedStatus = useRecoilValue(
allRowsSelectedStatusScopedSelector,
);
const { selectAllRows } = useRecordTable(); const { selectAllRows } = useRecordTable();
const checked = allRowsSelectedStatus === 'all'; const checked = allRowsSelectedStatus === 'all';

View File

@ -1,11 +1,24 @@
import React from 'react';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { ContextMenu } from '@/ui/navigation/context-menu/components/ContextMenu'; import { ContextMenu } from '@/ui/navigation/context-menu/components/ContextMenu';
import { selectedRowIdsSelector } from '../../states/selectors/selectedRowIdsSelector'; export const RecordTableContextMenu = ({
recordTableId,
}: {
recordTableId: string;
}) => {
const { selectedRowIdsScopeInjector } = getRecordTableScopeInjector();
const { injectSelectorWithRecordTableScopeId } =
useRecordTableScopedStates(recordTableId);
const selectedRowIdsSelector = injectSelectorWithRecordTableScopeId(
selectedRowIdsScopeInjector,
);
export const RecordTableContextMenu = () => {
const selectedRowIds = useRecoilValue(selectedRowIdsSelector); const selectedRowIds = useRecoilValue(selectedRowIdsSelector);
return <ContextMenu selectedIds={selectedRowIds} />; return <ContextMenu selectedIds={selectedRowIds} />;
}; };

View File

@ -1,18 +1,42 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { currentTableCellInEditModePositionState } from '../../states/currentTableCellInEditModePositionState'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { isTableCellInEditModeFamilyState } from '../../states/isTableCellInEditModeFamilyState'; import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
export const useCloseCurrentTableCellInEditMode = () => export const useCloseCurrentTableCellInEditMode = (
useRecoilCallback(({ set, snapshot }) => { recordTableScopeId: string,
return async () => { ) => {
const currentTableCellInEditModePosition = snapshot const {
.getLoadable(currentTableCellInEditModePositionState) currentTableCellInEditModePositionScopeInjector,
.valueOrThrow(); isTableCellInEditModeScopeInjector,
} = getRecordTableScopeInjector();
set( const {
isTableCellInEditModeFamilyState(currentTableCellInEditModePosition), injectSnapshotValueWithRecordTableScopeId,
false, injectFamilyStateWithRecordTableScopeId,
); } = useRecordTableScopedStates(recordTableScopeId);
};
}, []); return useRecoilCallback(
({ set, snapshot }) => {
return async () => {
const currentTableCellInEditModePosition =
injectSnapshotValueWithRecordTableScopeId(
snapshot,
currentTableCellInEditModePositionScopeInjector,
);
const isTableCellInEditMode = injectFamilyStateWithRecordTableScopeId(
isTableCellInEditModeScopeInjector,
);
set(isTableCellInEditMode(currentTableCellInEditModePosition), false);
};
},
[
currentTableCellInEditModePositionScopeInjector,
injectFamilyStateWithRecordTableScopeId,
injectSnapshotValueWithRecordTableScopeId,
isTableCellInEditModeScopeInjector,
],
);
};

View File

@ -1,18 +1,50 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { isSoftFocusActiveState } from '../../states/isSoftFocusActiveState'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { isSoftFocusOnTableCellFamilyState } from '../../states/isSoftFocusOnTableCellFamilyState'; import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { softFocusPositionState } from '../../states/softFocusPositionState';
export const useDisableSoftFocus = () => export const useDisableSoftFocus = (recordTableScopeId: string) => {
useRecoilCallback(({ set, snapshot }) => { const {
return () => { softFocusPositionScopeInjector,
const currentPosition = snapshot isSoftFocusActiveScopeInjector,
.getLoadable(softFocusPositionState) isSoftFocusOnTableCellScopeInjector,
.valueOrThrow(); } = getRecordTableScopeInjector();
set(isSoftFocusActiveState, false); const {
injectStateWithRecordTableScopeId,
injectSnapshotValueWithRecordTableScopeId,
injectFamilyStateWithRecordTableScopeId,
} = useRecordTableScopedStates(recordTableScopeId);
set(isSoftFocusOnTableCellFamilyState(currentPosition), false); return useRecoilCallback(
}; ({ set, snapshot }) => {
}, []); return () => {
const currentPosition = injectSnapshotValueWithRecordTableScopeId(
snapshot,
softFocusPositionScopeInjector,
);
const isSoftFocusActiveState = injectStateWithRecordTableScopeId(
isSoftFocusActiveScopeInjector,
);
const isSoftFocusOnTableCellFamilyState =
injectFamilyStateWithRecordTableScopeId(
isSoftFocusOnTableCellScopeInjector,
);
set(isSoftFocusActiveState, false);
set(isSoftFocusOnTableCellFamilyState(currentPosition), false);
};
},
[
injectFamilyStateWithRecordTableScopeId,
injectSnapshotValueWithRecordTableScopeId,
injectStateWithRecordTableScopeId,
isSoftFocusActiveScopeInjector,
isSoftFocusOnTableCellScopeInjector,
softFocusPositionScopeInjector,
],
);
};

View File

@ -1,26 +1,45 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { currentTableCellInEditModePositionState } from '../../states/currentTableCellInEditModePositionState'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { isTableCellInEditModeFamilyState } from '../../states/isTableCellInEditModeFamilyState'; import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
export const useGetIsSomeCellInEditMode = (recordTableScopeId: string) => {
const {
currentTableCellInEditModePositionScopeInjector,
isTableCellInEditModeScopeInjector,
} = getRecordTableScopeInjector();
const {
injectSnapshotValueWithRecordTableScopeId,
injectFamilySnapshotValueWithRecordTableScopeId,
} = useRecordTableScopedStates(recordTableScopeId);
export const useGetIsSomeCellInEditMode = () => {
return useRecoilCallback( return useRecoilCallback(
({ snapshot }) => ({ snapshot }) =>
() => { () => {
const currentTableCellInEditModePosition = snapshot const currentTableCellInEditModePosition =
.getLoadable(currentTableCellInEditModePositionState) injectSnapshotValueWithRecordTableScopeId(
.valueOrThrow(); snapshot,
currentTableCellInEditModePositionScopeInjector,
);
const isSomeCellInEditMode = snapshot const isSomeCellInEditModeFamilyState =
.getLoadable( injectFamilySnapshotValueWithRecordTableScopeId(
isTableCellInEditModeFamilyState( snapshot,
currentTableCellInEditModePosition, isTableCellInEditModeScopeInjector,
), );
)
.valueOrThrow(); const isSomeCellInEditMode = isSomeCellInEditModeFamilyState(
currentTableCellInEditModePosition,
);
return isSomeCellInEditMode; return isSomeCellInEditMode;
}, },
[], [
currentTableCellInEditModePositionScopeInjector,
injectFamilySnapshotValueWithRecordTableScopeId,
injectSnapshotValueWithRecordTableScopeId,
isTableCellInEditModeScopeInjector,
],
); );
}; };

View File

@ -1,23 +1,31 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState'; import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState';
import { isSoftFocusActiveState } from '../../states/isSoftFocusActiveState';
import { TableHotkeyScope } from '../../types/TableHotkeyScope'; import { TableHotkeyScope } from '../../types/TableHotkeyScope';
import { useCloseCurrentTableCellInEditMode } from './useCloseCurrentTableCellInEditMode'; import { useCloseCurrentTableCellInEditMode } from './useCloseCurrentTableCellInEditMode';
import { useDisableSoftFocus } from './useDisableSoftFocus'; import { useDisableSoftFocus } from './useDisableSoftFocus';
export const useLeaveTableFocus = () => { export const useLeaveTableFocus = (recordTableScopeId: string) => {
const disableSoftFocus = useDisableSoftFocus(); const disableSoftFocus = useDisableSoftFocus(recordTableScopeId);
const closeCurrentCellInEditMode = useCloseCurrentTableCellInEditMode(); const closeCurrentCellInEditMode =
useCloseCurrentTableCellInEditMode(recordTableScopeId);
const { isSoftFocusActiveScopeInjector } = getRecordTableScopeInjector();
const { injectSnapshotValueWithRecordTableScopeId } =
useRecordTableScopedStates(recordTableScopeId);
return useRecoilCallback( return useRecoilCallback(
({ snapshot }) => ({ snapshot }) =>
() => { () => {
const isSoftFocusActive = snapshot const isSoftFocusActive = injectSnapshotValueWithRecordTableScopeId(
.getLoadable(isSoftFocusActiveState) snapshot,
.valueOrThrow(); isSoftFocusActiveScopeInjector,
);
const currentHotkeyScope = snapshot const currentHotkeyScope = snapshot
.getLoadable(currentHotkeyScopeState) .getLoadable(currentHotkeyScopeState)
@ -34,6 +42,11 @@ export const useLeaveTableFocus = () => {
closeCurrentCellInEditMode(); closeCurrentCellInEditMode();
disableSoftFocus(); disableSoftFocus();
}, },
[closeCurrentCellInEditMode, disableSoftFocus], [
closeCurrentCellInEditMode,
disableSoftFocus,
injectSnapshotValueWithRecordTableScopeId,
isSoftFocusActiveScopeInjector,
],
); );
}; };

View File

@ -1,23 +1,59 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { currentTableCellInEditModePositionState } from '../../states/currentTableCellInEditModePositionState'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { isTableCellInEditModeFamilyState } from '../../states/isTableCellInEditModeFamilyState'; import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { TableCellPosition } from '../../types/TableCellPosition'; import { TableCellPosition } from '../../types/TableCellPosition';
export const useMoveEditModeToTableCellPosition = () => export const useMoveEditModeToTableCellPosition = (
useRecoilCallback(({ set, snapshot }) => { recordTableScopeId: string,
return (newPosition: TableCellPosition) => { ) => {
const currentTableCellInEditModePosition = snapshot const {
.getLoadable(currentTableCellInEditModePositionState) isTableCellInEditModeScopeInjector,
.valueOrThrow(); currentTableCellInEditModePositionScopeInjector,
} = getRecordTableScopeInjector();
set( const {
isTableCellInEditModeFamilyState(currentTableCellInEditModePosition), injectStateWithRecordTableScopeId,
false, injectSnapshotValueWithRecordTableScopeId,
); injectFamilyStateWithRecordTableScopeId,
} = useRecordTableScopedStates(recordTableScopeId);
set(currentTableCellInEditModePositionState, newPosition); return useRecoilCallback(
({ set, snapshot }) => {
return (newPosition: TableCellPosition) => {
const currentTableCellInEditModePosition =
injectSnapshotValueWithRecordTableScopeId(
snapshot,
currentTableCellInEditModePositionScopeInjector,
);
set(isTableCellInEditModeFamilyState(newPosition), true); const currentTableCellInEditModePositionState =
}; injectStateWithRecordTableScopeId(
}, []); currentTableCellInEditModePositionScopeInjector,
);
const isTableCellInEditModeFamilyState =
injectFamilyStateWithRecordTableScopeId(
isTableCellInEditModeScopeInjector,
);
set(
isTableCellInEditModeFamilyState(currentTableCellInEditModePosition),
false,
);
set(currentTableCellInEditModePositionState, newPosition);
set(isTableCellInEditModeFamilyState(newPosition), true);
};
},
[
currentTableCellInEditModePositionScopeInjector,
injectFamilyStateWithRecordTableScopeId,
injectSnapshotValueWithRecordTableScopeId,
injectStateWithRecordTableScopeId,
isTableCellInEditModeScopeInjector,
],
);
};

View File

@ -1,46 +1,31 @@
import { RecordTableScopeInternalContext } from '@/object-record/record-table/scopes/scope-internal-context/RecordTableScopeInternalContext'; import { RecordTableScopeInternalContext } from '@/object-record/record-table/scopes/scope-internal-context/RecordTableScopeInternalContext';
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { useScopedState } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useScopedState';
import { getRecordTableScopedStates } from '../../utils/getRecordTableScopedStates'; export const useRecordTableScopedStates = (recordTableId?: string) => {
export const useRecordTableScopedStates = (args?: {
customRecordTableScopeId?: string;
}) => {
const { customRecordTableScopeId } = args ?? {};
const scopeId = useAvailableScopeIdOrThrow( const scopeId = useAvailableScopeIdOrThrow(
RecordTableScopeInternalContext, RecordTableScopeInternalContext,
customRecordTableScopeId, recordTableId,
); );
const { const {
availableTableColumnsState, getScopedState,
tableFiltersState, getScopedSelector,
tableSortsState, getScopedFamilyState,
tableColumnsState, getScopedSnapshotValue,
objectMetadataConfigState, getScopedSelectorSnapshotValue,
tableColumnsByKeySelector, getScopedFamilySnapshotValue,
hiddenTableColumnsSelector, } = useScopedState(scopeId);
visibleTableColumnsSelector,
onEntityCountChangeState,
onColumnsChangeState,
tableLastRowVisibleState,
} = getRecordTableScopedStates({
recordTableScopeId: scopeId,
});
return { return {
scopeId, scopeId,
availableTableColumnsState, injectStateWithRecordTableScopeId: getScopedState,
tableFiltersState, injectSelectorWithRecordTableScopeId: getScopedSelector,
tableSortsState, injectFamilyStateWithRecordTableScopeId: getScopedFamilyState,
tableColumnsState, injectSelectorSnapshotValueWithRecordTableScopeId:
objectMetadataConfigState, getScopedSelectorSnapshotValue,
tableColumnsByKeySelector, injectSnapshotValueWithRecordTableScopeId: getScopedSnapshotValue,
hiddenTableColumnsSelector, injectFamilySnapshotValueWithRecordTableScopeId:
visibleTableColumnsSelector, getScopedFamilySnapshotValue,
onEntityCountChangeState,
onColumnsChangeState,
tableLastRowVisibleState,
}; };
}; };

View File

@ -1,19 +1,37 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { isRowSelectedFamilyState } from '../../record-table-row/states/isRowSelectedFamilyState'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { tableRowIdsState } from '../../states/tableRowIdsState'; import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
export const useResetTableRowSelection = () => export const useResetTableRowSelection = (recordTableScopeId: string) => {
useRecoilCallback( const { tableRowIdsScopeInjector, isRowSelectedScopeInjector } =
getRecordTableScopeInjector();
const {
injectSnapshotValueWithRecordTableScopeId,
injectFamilyStateWithRecordTableScopeId,
} = useRecordTableScopedStates(recordTableScopeId);
return useRecoilCallback(
({ snapshot, set }) => ({ snapshot, set }) =>
() => { () => {
const tableRowIds = snapshot const tableRowIds = injectSnapshotValueWithRecordTableScopeId(
.getLoadable(tableRowIdsState) snapshot,
.valueOrThrow(); tableRowIdsScopeInjector,
);
const isRowSelectedFamilyState =
injectFamilyStateWithRecordTableScopeId(isRowSelectedScopeInjector);
for (const rowId of tableRowIds) { for (const rowId of tableRowIds) {
set(isRowSelectedFamilyState(rowId), false); set(isRowSelectedFamilyState(rowId), false);
} }
}, },
[], [
injectFamilyStateWithRecordTableScopeId,
injectSnapshotValueWithRecordTableScopeId,
isRowSelectedScopeInjector,
tableRowIdsScopeInjector,
],
); );
};

View File

@ -1,20 +1,37 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { isRowSelectedFamilyState } from '../../record-table-row/states/isRowSelectedFamilyState'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { allRowsSelectedStatusSelector } from '../../states/selectors/allRowsSelectedStatusSelector'; import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { tableRowIdsState } from '../../states/tableRowIdsState';
export const useSelectAllRows = (recordTableScopeId: string) => {
const {
allRowsSelectedStatusScopeInjector,
tableRowIdsScopeInjector,
isRowSelectedScopeInjector,
} = getRecordTableScopeInjector();
const {
injectSnapshotValueWithRecordTableScopeId,
injectSelectorSnapshotValueWithRecordTableScopeId,
injectFamilyStateWithRecordTableScopeId,
} = useRecordTableScopedStates(recordTableScopeId);
export const useSelectAllRows = () => {
const selectAllRows = useRecoilCallback( const selectAllRows = useRecoilCallback(
({ set, snapshot }) => ({ set, snapshot }) =>
() => { () => {
const allRowsSelectedStatus = snapshot const allRowsSelectedStatus =
.getLoadable(allRowsSelectedStatusSelector) injectSelectorSnapshotValueWithRecordTableScopeId(
.valueOrThrow(); snapshot,
allRowsSelectedStatusScopeInjector,
);
const tableRowIds = snapshot const tableRowIds = injectSnapshotValueWithRecordTableScopeId(
.getLoadable(tableRowIdsState) snapshot,
.valueOrThrow(); tableRowIdsScopeInjector,
);
const isRowSelectedFamilyState =
injectFamilyStateWithRecordTableScopeId(isRowSelectedScopeInjector);
if ( if (
allRowsSelectedStatus === 'none' || allRowsSelectedStatus === 'none' ||
@ -29,7 +46,14 @@ export const useSelectAllRows = () => {
} }
} }
}, },
[], [
allRowsSelectedStatusScopeInjector,
injectFamilyStateWithRecordTableScopeId,
injectSelectorSnapshotValueWithRecordTableScopeId,
injectSnapshotValueWithRecordTableScopeId,
isRowSelectedScopeInjector,
tableRowIdsScopeInjector,
],
); );
return { return {

View File

@ -1,25 +1,35 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState'; import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { useResetTableRowSelection } from '@/object-record/record-table/hooks/internal/useResetTableRowSelection'; import { useResetTableRowSelection } from '@/object-record/record-table/hooks/internal/useResetTableRowSelection';
import { numberOfTableRowsState } from '@/object-record/record-table/states/numberOfTableRowsState'; import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
import { tableRowIdsState } from '../../states/tableRowIdsState';
type useSetRecordTableDataProps = { type useSetRecordTableDataProps = {
recordTableScopeId: string;
onEntityCountChange: (entityCount: number) => void; onEntityCountChange: (entityCount: number) => void;
}; };
export const useSetRecordTableData = ({ export const useSetRecordTableData = ({
recordTableScopeId,
onEntityCountChange, onEntityCountChange,
}: useSetRecordTableDataProps) => { }: useSetRecordTableDataProps) => {
const resetTableRowSelection = useResetTableRowSelection(); const resetTableRowSelection = useResetTableRowSelection(recordTableScopeId);
const { tableRowIdsScopeInjector, numberOfTableRowsScopeInjector } =
getRecordTableScopeInjector();
const {
injectStateWithRecordTableScopeId,
injectSnapshotValueWithRecordTableScopeId,
} = useRecordTableScopedStates(recordTableScopeId);
return useRecoilCallback( return useRecoilCallback(
({ set, snapshot }) => ({ set, snapshot }) =>
<T extends { id: string }>(newEntityArray: T[]) => { <T extends { id: string }>(newEntityArray: T[]) => {
for (const entity of newEntityArray) { for (const entity of newEntityArray) {
// TODO: refactor with scoped state later
const currentEntity = snapshot const currentEntity = snapshot
.getLoadable(entityFieldsFamilyState(entity.id)) .getLoadable(entityFieldsFamilyState(entity.id))
.valueOrThrow(); .valueOrThrow();
@ -28,19 +38,37 @@ export const useSetRecordTableData = ({
set(entityFieldsFamilyState(entity.id), entity); set(entityFieldsFamilyState(entity.id), entity);
} }
} }
const currentRowIds = snapshot.getLoadable(tableRowIdsState).getValue(); const currentRowIds = injectSnapshotValueWithRecordTableScopeId(
snapshot,
tableRowIdsScopeInjector,
);
const entityIds = newEntityArray.map((entity) => entity.id); const entityIds = newEntityArray.map((entity) => entity.id);
const tableRowIdsState = injectStateWithRecordTableScopeId(
tableRowIdsScopeInjector,
);
if (!isDeeplyEqual(currentRowIds, entityIds)) { if (!isDeeplyEqual(currentRowIds, entityIds)) {
set(tableRowIdsState, entityIds); set(tableRowIdsState, entityIds);
} }
resetTableRowSelection(); resetTableRowSelection();
const numberOfTableRowsState = injectStateWithRecordTableScopeId(
numberOfTableRowsScopeInjector,
);
set(numberOfTableRowsState, entityIds.length); set(numberOfTableRowsState, entityIds.length);
onEntityCountChange(entityIds.length); onEntityCountChange(entityIds.length);
}, },
[onEntityCountChange, resetTableRowSelection], [
injectSnapshotValueWithRecordTableScopeId,
injectStateWithRecordTableScopeId,
numberOfTableRowsScopeInjector,
onEntityCountChange,
resetTableRowSelection,
tableRowIdsScopeInjector,
],
); );
}; };

View File

@ -1,8 +1,19 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { isRowSelectedFamilyState } from '../../record-table-row/states/isRowSelectedFamilyState'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
export const useSetRowSelectedState = () => export const useSetRowSelectedState = (recordTableScopeId: string) => {
useRecoilCallback(({ set }) => (rowId: string, selected: boolean) => { const { isRowSelectedScopeInjector } = getRecordTableScopeInjector();
const { injectFamilyStateWithRecordTableScopeId } =
useRecordTableScopedStates(recordTableScopeId);
const isRowSelectedFamilyState = injectFamilyStateWithRecordTableScopeId(
isRowSelectedScopeInjector,
);
return useRecoilCallback(({ set }) => (rowId: string, selected: boolean) => {
set(isRowSelectedFamilyState(rowId), selected); set(isRowSelectedFamilyState(rowId), selected);
}); });
};

View File

@ -1,23 +1,60 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { isSoftFocusActiveState } from '../../states/isSoftFocusActiveState'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { isSoftFocusOnTableCellFamilyState } from '../../states/isSoftFocusOnTableCellFamilyState'; import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { softFocusPositionState } from '../../states/softFocusPositionState';
import { TableCellPosition } from '../../types/TableCellPosition'; import { TableCellPosition } from '../../types/TableCellPosition';
export const useSetSoftFocusPosition = () => export const useSetSoftFocusPosition = (recordTableScopeId: string) => {
useRecoilCallback(({ set, snapshot }) => { const {
return (newPosition: TableCellPosition) => { softFocusPositionScopeInjector,
const currentPosition = snapshot isSoftFocusActiveScopeInjector,
.getLoadable(softFocusPositionState) isSoftFocusOnTableCellScopeInjector,
.valueOrThrow(); } = getRecordTableScopeInjector();
set(isSoftFocusActiveState, true); const {
injectStateWithRecordTableScopeId,
injectSnapshotValueWithRecordTableScopeId,
injectFamilyStateWithRecordTableScopeId,
} = useRecordTableScopedStates(recordTableScopeId);
set(isSoftFocusOnTableCellFamilyState(currentPosition), false); return useRecoilCallback(
({ set, snapshot }) => {
return (newPosition: TableCellPosition) => {
const currentPosition = injectSnapshotValueWithRecordTableScopeId(
snapshot,
softFocusPositionScopeInjector,
);
set(softFocusPositionState, newPosition); const isSoftFocusActiveState = injectStateWithRecordTableScopeId(
isSoftFocusActiveScopeInjector,
);
set(isSoftFocusOnTableCellFamilyState(newPosition), true); const isSoftFocusOnTableCellFamilyState =
}; injectFamilyStateWithRecordTableScopeId(
}, []); isSoftFocusOnTableCellScopeInjector,
);
const softFocusPositionState = injectStateWithRecordTableScopeId(
softFocusPositionScopeInjector,
);
set(isSoftFocusActiveState, true);
set(isSoftFocusOnTableCellFamilyState(currentPosition), false);
set(softFocusPositionState, newPosition);
set(isSoftFocusOnTableCellFamilyState(newPosition), true);
};
},
[
injectFamilyStateWithRecordTableScopeId,
injectSnapshotValueWithRecordTableScopeId,
injectStateWithRecordTableScopeId,
isSoftFocusActiveScopeInjector,
isSoftFocusOnTableCellScopeInjector,
softFocusPositionScopeInjector,
],
);
};

View File

@ -3,8 +3,9 @@ import { useRecoilCallback } from 'recoil';
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState'; import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
export const useUpsertRecordTableItem = () => // TODO: refactor with scoped state later
useRecoilCallback( export const useUpsertRecordTableItem = () => {
return useRecoilCallback(
({ set, snapshot }) => ({ set, snapshot }) =>
<T extends { id: string }>(entity: T) => { <T extends { id: string }>(entity: T) => {
const currentEntity = snapshot const currentEntity = snapshot
@ -17,3 +18,4 @@ export const useUpsertRecordTableItem = () =>
}, },
[], [],
); );
};

View File

@ -1,8 +1,9 @@
import { useRecoilCallback, useSetRecoilState } from 'recoil'; import { useRecoilCallback, useSetRecoilState } from 'recoil';
import { Key } from 'ts-key-enum'; import { Key } from 'ts-key-enum';
import { useGetIsSomeCellInEditMode } from '@/object-record/record-table/hooks/internal/useGetIsSomeCellInEditMode';
import { RecordTableScopeInternalContext } from '@/object-record/record-table/scopes/scope-internal-context/RecordTableScopeInternalContext'; import { RecordTableScopeInternalContext } from '@/object-record/record-table/scopes/scope-internal-context/RecordTableScopeInternalContext';
import { onColumnsChangeScopedState } from '@/object-record/record-table/states/onColumnsChangeScopedState'; import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
@ -10,10 +11,7 @@ import { getScopedStateDeprecated } from '@/ui/utilities/recoil-scope/utils/getS
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
import { FieldMetadata } from '../../field/types/FieldMetadata'; import { FieldMetadata } from '../../field/types/FieldMetadata';
import { numberOfTableRowsState } from '../states/numberOfTableRowsState'; import { onEntityCountChangeScopedState } from '../states/onEntityCountChangeScopedState';
import { onEntityCountChangeScopedState } from '../states/onEntityCountChange';
import { numberOfTableColumnsScopedSelector } from '../states/selectors/numberOfTableColumnsScopedSelector';
import { softFocusPositionState } from '../states/softFocusPositionState';
import { ColumnDefinition } from '../types/ColumnDefinition'; import { ColumnDefinition } from '../types/ColumnDefinition';
import { TableHotkeyScope } from '../types/TableHotkeyScope'; import { TableHotkeyScope } from '../types/TableHotkeyScope';
@ -38,43 +36,71 @@ export const useRecordTable = (props?: useRecordTableProps) => {
); );
const { const {
availableTableColumnsState, injectStateWithRecordTableScopeId,
tableFiltersState, injectSnapshotValueWithRecordTableScopeId,
tableSortsState, injectSelectorSnapshotValueWithRecordTableScopeId,
tableColumnsState, } = useRecordTableScopedStates(scopeId);
objectMetadataConfigState,
onEntityCountChangeState, const {
} = useRecordTableScopedStates({ availableTableColumnsScopeInjector,
customRecordTableScopeId: scopeId, tableFiltersScopeInjector,
}); tableSortsScopeInjector,
tableColumnsScopeInjector,
objectMetadataConfigScopeInjector,
onEntityCountScopeInjector,
softFocusPositionScopeInjector,
numberOfTableRowsScopeInjector,
numberOfTableColumnsScopeInjector,
onColumnsChangeScopeInjector,
isRecordTableInitialLoadingScopeInjector,
tableLastRowVisibleScopeInjector,
} = getRecordTableScopeInjector();
const setAvailableTableColumns = useSetRecoilState( const setAvailableTableColumns = useSetRecoilState(
availableTableColumnsState, injectStateWithRecordTableScopeId(availableTableColumnsScopeInjector),
); );
const setOnEntityCountChange = useSetRecoilState(onEntityCountChangeState); const setOnEntityCountChange = useSetRecoilState(
const setTableFilters = useSetRecoilState(tableFiltersState); injectStateWithRecordTableScopeId(onEntityCountScopeInjector),
const setObjectMetadataConfig = useSetRecoilState(objectMetadataConfigState); );
const setTableFilters = useSetRecoilState(
injectStateWithRecordTableScopeId(tableFiltersScopeInjector),
);
const setObjectMetadataConfig = useSetRecoilState(
injectStateWithRecordTableScopeId(objectMetadataConfigScopeInjector),
);
const setTableSorts = useSetRecoilState(tableSortsState); const setTableSorts = useSetRecoilState(
injectStateWithRecordTableScopeId(tableSortsScopeInjector),
);
const setTableColumns = useSetRecoilState(tableColumnsState); const setTableColumns = useSetRecoilState(
injectStateWithRecordTableScopeId(tableColumnsScopeInjector),
);
const setOnColumnsChange = useSetRecoilState(
injectStateWithRecordTableScopeId(onColumnsChangeScopeInjector),
);
const setIsRecordTableInitialLoading = useSetRecoilState(
injectStateWithRecordTableScopeId(isRecordTableInitialLoadingScopeInjector),
);
const setRecordTableLastRowVisible = useSetRecoilState(
injectStateWithRecordTableScopeId(tableLastRowVisibleScopeInjector),
);
const onColumnsChange = useRecoilCallback( const onColumnsChange = useRecoilCallback(
({ snapshot }) => ({ snapshot }) =>
(columns: ColumnDefinition<FieldMetadata>[]) => { (columns: ColumnDefinition<FieldMetadata>[]) => {
const onColumnsChangeState = getScopedStateDeprecated( const onColumnsChange = injectSnapshotValueWithRecordTableScopeId(
onColumnsChangeScopedState,
scopeId,
);
const onColumnsChange = getSnapshotValue(
snapshot, snapshot,
onColumnsChangeState, onColumnsChangeScopeInjector,
); );
onColumnsChange?.(columns); onColumnsChange?.(columns);
}, },
[scopeId], [injectSnapshotValueWithRecordTableScopeId, onColumnsChangeScopeInjector],
); );
const onEntityCountChange = useRecoilCallback( const onEntityCountChange = useRecoilCallback(
@ -94,24 +120,28 @@ export const useRecordTable = (props?: useRecordTableProps) => {
[scopeId], [scopeId],
); );
const setRecordTableData = useSetRecordTableData({ onEntityCountChange }); const setRecordTableData = useSetRecordTableData({
recordTableScopeId: scopeId,
onEntityCountChange,
});
const leaveTableFocus = useLeaveTableFocus(); const leaveTableFocus = useLeaveTableFocus(scopeId);
const setRowSelectedState = useSetRowSelectedState(); const setRowSelectedState = useSetRowSelectedState(scopeId);
const resetTableRowSelection = useResetTableRowSelection(); const resetTableRowSelection = useResetTableRowSelection(scopeId);
const upsertRecordTableItem = useUpsertRecordTableItem(); const upsertRecordTableItem = useUpsertRecordTableItem();
const setSoftFocusPosition = useSetSoftFocusPosition(); const setSoftFocusPosition = useSetSoftFocusPosition(scopeId);
const moveUp = useRecoilCallback( const moveUp = useRecoilCallback(
({ snapshot }) => ({ snapshot }) =>
() => { () => {
const softFocusPosition = snapshot const softFocusPosition = injectSnapshotValueWithRecordTableScopeId(
.getLoadable(softFocusPositionState) snapshot,
.valueOrThrow(); softFocusPositionScopeInjector,
);
let newRowNumber = softFocusPosition.row - 1; let newRowNumber = softFocusPosition.row - 1;
@ -124,19 +154,25 @@ export const useRecordTable = (props?: useRecordTableProps) => {
row: newRowNumber, row: newRowNumber,
}); });
}, },
[setSoftFocusPosition], [
injectSnapshotValueWithRecordTableScopeId,
setSoftFocusPosition,
softFocusPositionScopeInjector,
],
); );
const moveDown = useRecoilCallback( const moveDown = useRecoilCallback(
({ snapshot }) => ({ snapshot }) =>
() => { () => {
const softFocusPosition = snapshot const softFocusPosition = injectSnapshotValueWithRecordTableScopeId(
.getLoadable(softFocusPositionState) snapshot,
.valueOrThrow(); softFocusPositionScopeInjector,
);
const numberOfTableRows = snapshot const numberOfTableRows = injectSnapshotValueWithRecordTableScopeId(
.getLoadable(numberOfTableRowsState) snapshot,
.valueOrThrow(); numberOfTableRowsScopeInjector,
);
let newRowNumber = softFocusPosition.row + 1; let newRowNumber = softFocusPosition.row + 1;
@ -149,24 +185,32 @@ export const useRecordTable = (props?: useRecordTableProps) => {
row: newRowNumber, row: newRowNumber,
}); });
}, },
[setSoftFocusPosition], [
injectSnapshotValueWithRecordTableScopeId,
numberOfTableRowsScopeInjector,
setSoftFocusPosition,
softFocusPositionScopeInjector,
],
); );
const moveRight = useRecoilCallback( const moveRight = useRecoilCallback(
({ snapshot }) => ({ snapshot }) =>
() => { () => {
const softFocusPosition = snapshot const softFocusPosition = injectSnapshotValueWithRecordTableScopeId(
.getLoadable(softFocusPositionState) snapshot,
.valueOrThrow(); softFocusPositionScopeInjector,
);
const numberOfTableColumns = snapshot const numberOfTableColumns =
.getLoadable(numberOfTableColumnsScopedSelector(scopeId)) injectSelectorSnapshotValueWithRecordTableScopeId(
.valueOrThrow(); snapshot,
numberOfTableColumnsScopeInjector,
const numberOfTableRows = snapshot );
.getLoadable(numberOfTableRowsState)
.valueOrThrow();
const numberOfTableRows = injectSnapshotValueWithRecordTableScopeId(
snapshot,
numberOfTableRowsScopeInjector,
);
const currentColumnNumber = softFocusPosition.column; const currentColumnNumber = softFocusPosition.column;
const currentRowNumber = softFocusPosition.row; const currentRowNumber = softFocusPosition.row;
@ -197,19 +241,29 @@ export const useRecordTable = (props?: useRecordTableProps) => {
}); });
} }
}, },
[scopeId, setSoftFocusPosition], [
injectSelectorSnapshotValueWithRecordTableScopeId,
injectSnapshotValueWithRecordTableScopeId,
numberOfTableColumnsScopeInjector,
numberOfTableRowsScopeInjector,
setSoftFocusPosition,
softFocusPositionScopeInjector,
],
); );
const moveLeft = useRecoilCallback( const moveLeft = useRecoilCallback(
({ snapshot }) => ({ snapshot }) =>
() => { () => {
const softFocusPosition = snapshot const softFocusPosition = injectSnapshotValueWithRecordTableScopeId(
.getLoadable(softFocusPositionState) snapshot,
.valueOrThrow(); softFocusPositionScopeInjector,
);
const numberOfTableColumns = snapshot const numberOfTableColumns =
.getLoadable(numberOfTableColumnsScopedSelector(scopeId)) injectSelectorSnapshotValueWithRecordTableScopeId(
.valueOrThrow(); snapshot,
numberOfTableColumnsScopeInjector,
);
const currentColumnNumber = softFocusPosition.column; const currentColumnNumber = softFocusPosition.column;
const currentRowNumber = softFocusPosition.row; const currentRowNumber = softFocusPosition.row;
@ -238,11 +292,17 @@ export const useRecordTable = (props?: useRecordTableProps) => {
}); });
} }
}, },
[scopeId, setSoftFocusPosition], [
injectSelectorSnapshotValueWithRecordTableScopeId,
injectSnapshotValueWithRecordTableScopeId,
numberOfTableColumnsScopeInjector,
setSoftFocusPosition,
softFocusPositionScopeInjector,
],
); );
const useMapKeyboardToSoftFocus = () => { const useMapKeyboardToSoftFocus = () => {
const disableSoftFocus = useDisableSoftFocus(); const disableSoftFocus = useDisableSoftFocus(scopeId);
const setHotkeyScope = useSetHotkeyScope(); const setHotkeyScope = useSetHotkeyScope();
useScopedHotkeys( useScopedHotkeys(
@ -295,7 +355,9 @@ export const useRecordTable = (props?: useRecordTableProps) => {
); );
}; };
const { selectAllRows } = useSelectAllRows(); const { selectAllRows } = useSelectAllRows(scopeId);
const getIsSomeCellInEditMode = useGetIsSomeCellInEditMode(scopeId);
return { return {
scopeId, scopeId,
@ -317,5 +379,10 @@ export const useRecordTable = (props?: useRecordTableProps) => {
moveUp, moveUp,
useMapKeyboardToSoftFocus, useMapKeyboardToSoftFocus,
selectAllRows, selectAllRows,
setOnColumnsChange,
setIsRecordTableInitialLoading,
setRecordTableLastRowVisible,
setSoftFocusPosition,
getIsSomeCellInEditMode,
}; };
}; };

View File

@ -4,6 +4,7 @@ import { useRecoilValue } from 'recoil';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata'; import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { RecordTableScopeInternalContext } from '@/object-record/record-table/scopes/scope-internal-context/RecordTableScopeInternalContext'; import { RecordTableScopeInternalContext } from '@/object-record/record-table/scopes/scope-internal-context/RecordTableScopeInternalContext';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { useMoveViewColumns } from '@/views/hooks/useMoveViewColumns'; import { useMoveViewColumns } from '@/views/hooks/useMoveViewColumns';
@ -25,12 +26,27 @@ export const useTableColumns = (props?: useRecordTableProps) => {
}); });
const { const {
availableTableColumnsState, injectStateWithRecordTableScopeId,
tableColumnsState, injectSelectorWithRecordTableScopeId,
visibleTableColumnsSelector, } = useRecordTableScopedStates(scopeId);
} = useRecordTableScopedStates({
customRecordTableScopeId: scopeId, const {
}); availableTableColumnsScopeInjector,
tableColumnsScopeInjector,
visibleTableColumnsScopeInjector,
} = getRecordTableScopeInjector();
const availableTableColumnsState = injectStateWithRecordTableScopeId(
availableTableColumnsScopeInjector,
);
const tableColumnsState = injectStateWithRecordTableScopeId(
tableColumnsScopeInjector,
);
const visibleTableColumnsSelector = injectSelectorWithRecordTableScopeId(
visibleTableColumnsScopeInjector,
);
const availableTableColumns = useRecoilValue(availableTableColumnsState); const availableTableColumns = useRecoilValue(availableTableColumnsState);

View File

@ -3,9 +3,9 @@ import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/Styl
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
export const TableOptionsDropdownButton = () => { export const TableOptionsDropdownButton = () => {
const { isDropdownOpen, toggleDropdown } = useDropdown({ const { isDropdownOpen, toggleDropdown } = useDropdown(
dropdownScopeId: TableOptionsDropdownId, TableOptionsDropdownId,
}); );
return ( return (
<StyledHeaderDropdownButton <StyledHeaderDropdownButton

View File

@ -3,6 +3,8 @@ import { OnDragEndResponder } from '@hello-pangea/dnd';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { Key } from 'ts-key-enum'; import { Key } from 'ts-key-enum';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { IconChevronLeft, IconFileImport, IconTag } from '@/ui/display/icon'; import { IconChevronLeft, IconFileImport, IconTag } from '@/ui/display/icon';
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader'; import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
import { DropdownMenuInput } from '@/ui/layout/dropdown/components/DropdownMenuInput'; import { DropdownMenuInput } from '@/ui/layout/dropdown/components/DropdownMenuInput';
@ -15,7 +17,6 @@ import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFiel
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates'; import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
import { useViewBar } from '@/views/hooks/useViewBar'; import { useViewBar } from '@/views/hooks/useViewBar';
import { useRecordTableScopedStates } from '../../hooks/internal/useRecordTableScopedStates';
import { useTableColumns } from '../../hooks/useTableColumns'; import { useTableColumns } from '../../hooks/useTableColumns';
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope'; import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
@ -41,8 +42,19 @@ export const TableOptionsDropdownContent = ({
const viewEditInputRef = useRef<HTMLInputElement>(null); const viewEditInputRef = useRef<HTMLInputElement>(null);
const { hiddenTableColumnsSelector, visibleTableColumnsSelector } = const { hiddenTableColumnsScopeInjector, visibleTableColumnsScopeInjector } =
useRecordTableScopedStates({ customRecordTableScopeId: recordTableId }); getRecordTableScopeInjector();
const { injectSelectorWithRecordTableScopeId } =
useRecordTableScopedStates(recordTableId);
const hiddenTableColumnsSelector = injectSelectorWithRecordTableScopeId(
hiddenTableColumnsScopeInjector,
);
const visibleTableColumnsSelector = injectSelectorWithRecordTableScopeId(
visibleTableColumnsScopeInjector,
);
const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector); const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector);
const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector); const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector);

View File

@ -8,7 +8,7 @@ import { useTableCell } from '../hooks/useTableCell';
import { TableCellContainer } from './RecordTableCellContainer'; import { TableCellContainer } from './RecordTableCellContainer';
export const TableCell = ({ export const RecordTableCell = ({
customHotkeyScope, customHotkeyScope,
}: { }: {
customHotkeyScope: HotkeyScope; customHotkeyScope: HotkeyScope;

View File

@ -9,12 +9,15 @@ const StyledEditButtonContainer = styled(motion.div)`
right: 5px; right: 5px;
`; `;
type TableCellButtonProps = { type RecordTableCellButtonProps = {
onClick?: () => void; onClick?: () => void;
Icon: IconComponent; Icon: IconComponent;
}; };
export const TableCellButton = ({ onClick, Icon }: TableCellButtonProps) => ( export const RecordTableCellButton = ({
onClick,
Icon,
}: RecordTableCellButtonProps) => (
<StyledEditButtonContainer <StyledEditButtonContainer
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
animate={{ opacity: 1 }} animate={{ opacity: 1 }}

View File

@ -4,7 +4,7 @@ import styled from '@emotion/styled';
import { useGetButtonIcon } from '@/object-record/field/hooks/useGetButtonIcon'; import { useGetButtonIcon } from '@/object-record/field/hooks/useGetButtonIcon';
import { useIsFieldEmpty } from '@/object-record/field/hooks/useIsFieldEmpty'; import { useIsFieldEmpty } from '@/object-record/field/hooks/useIsFieldEmpty';
import { useIsFieldInputOnly } from '@/object-record/field/hooks/useIsFieldInputOnly'; import { useIsFieldInputOnly } from '@/object-record/field/hooks/useIsFieldInputOnly';
import { useGetIsSomeCellInEditMode } from '@/object-record/record-table/hooks/internal/useGetIsSomeCellInEditMode'; import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { IconArrowUpRight } from '@/ui/display/icon'; import { IconArrowUpRight } from '@/ui/display/icon';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
@ -17,10 +17,10 @@ import { useMoveSoftFocusToCurrentCellOnHover } from '../hooks/useMoveSoftFocusT
import { useSetSoftFocusOnCurrentTableCell } from '../hooks/useSetSoftFocusOnCurrentTableCell'; import { useSetSoftFocusOnCurrentTableCell } from '../hooks/useSetSoftFocusOnCurrentTableCell';
import { useTableCell } from '../hooks/useTableCell'; import { useTableCell } from '../hooks/useTableCell';
import { TableCellButton } from './RecordTableCellButton'; import { RecordTableCellButton } from './RecordTableCellButton';
import { TableCellDisplayMode } from './RecordTableCellDisplayMode'; import { RecordTableCellDisplayMode } from './RecordTableCellDisplayMode';
import { TableCellEditMode } from './RecordTableCellEditMode'; import { RecordTableCellEditMode } from './RecordTableCellEditMode';
import { TableCellSoftFocusMode } from './RecordTableCellSoftFocusMode'; import { RecordTableCellSoftFocusMode } from './RecordTableCellSoftFocusMode';
const StyledCellBaseContainer = styled.div` const StyledCellBaseContainer = styled.div`
align-items: center; align-items: center;
@ -57,7 +57,7 @@ export const TableCellContainer = ({
}: TableCellContainerProps) => { }: TableCellContainerProps) => {
const { isCurrentTableCellInEditMode } = useCurrentTableCellEditMode(); const { isCurrentTableCellInEditMode } = useCurrentTableCellEditMode();
const getIsSomeCellInEditMode = useGetIsSomeCellInEditMode(); const { getIsSomeCellInEditMode } = useRecordTable();
const [isHovered, setIsHovered] = useState(false); const [isHovered, setIsHovered] = useState(false);
@ -116,29 +116,35 @@ export const TableCellContainer = ({
onMouseLeave={handleContainerMouseLeave} onMouseLeave={handleContainerMouseLeave}
> >
{isCurrentTableCellInEditMode ? ( {isCurrentTableCellInEditMode ? (
<TableCellEditMode <RecordTableCellEditMode
editModeHorizontalAlign={editModeHorizontalAlign} editModeHorizontalAlign={editModeHorizontalAlign}
editModeVerticalPosition={editModeVerticalPosition} editModeVerticalPosition={editModeVerticalPosition}
> >
{editModeContent} {editModeContent}
</TableCellEditMode> </RecordTableCellEditMode>
) : hasSoftFocus ? ( ) : hasSoftFocus ? (
<> <>
{showButton && ( {showButton && (
<TableCellButton onClick={handleButtonClick} Icon={buttonIcon} /> <RecordTableCellButton
onClick={handleButtonClick}
Icon={buttonIcon}
/>
)} )}
<TableCellSoftFocusMode> <RecordTableCellSoftFocusMode>
{editModeContentOnly ? editModeContent : nonEditModeContent} {editModeContentOnly ? editModeContent : nonEditModeContent}
</TableCellSoftFocusMode> </RecordTableCellSoftFocusMode>
</> </>
) : ( ) : (
<> <>
{showButton && ( {showButton && (
<TableCellButton onClick={handleButtonClick} Icon={buttonIcon} /> <RecordTableCellButton
onClick={handleButtonClick}
Icon={buttonIcon}
/>
)} )}
<TableCellDisplayMode> <RecordTableCellDisplayMode>
{editModeContentOnly ? editModeContent : nonEditModeContent} {editModeContentOnly ? editModeContent : nonEditModeContent}
</TableCellDisplayMode> </RecordTableCellDisplayMode>
</> </>
)} )}
</StyledCellBaseContainer> </StyledCellBaseContainer>

View File

@ -34,7 +34,7 @@ const StyledEditableCellDisplayModeInnerContainer = styled.div`
width: 100%; width: 100%;
`; `;
export const TableCellDisplayContainer = ({ export const RecordTableCellDisplayContainer = ({
children, children,
softFocus, softFocus,
onClick, onClick,

View File

@ -3,9 +3,9 @@ import { useIsFieldInputOnly } from '@/object-record/field/hooks/useIsFieldInput
import { useSetSoftFocusOnCurrentTableCell } from '../hooks/useSetSoftFocusOnCurrentTableCell'; import { useSetSoftFocusOnCurrentTableCell } from '../hooks/useSetSoftFocusOnCurrentTableCell';
import { useTableCell } from '../hooks/useTableCell'; import { useTableCell } from '../hooks/useTableCell';
import { TableCellDisplayContainer } from './RecordTableCellDisplayContainer'; import { RecordTableCellDisplayContainer } from './RecordTableCellDisplayContainer';
export const TableCellDisplayMode = ({ export const RecordTableCellDisplayMode = ({
children, children,
}: React.PropsWithChildren<unknown>) => { }: React.PropsWithChildren<unknown>) => {
const setSoftFocusOnCurrentCell = useSetSoftFocusOnCurrentTableCell(); const setSoftFocusOnCurrentCell = useSetSoftFocusOnCurrentTableCell();
@ -23,8 +23,8 @@ export const TableCellDisplayMode = ({
}; };
return ( return (
<TableCellDisplayContainer onClick={handleClick}> <RecordTableCellDisplayContainer onClick={handleClick}>
{children} {children}
</TableCellDisplayContainer> </RecordTableCellDisplayContainer>
); );
}; };

View File

@ -9,12 +9,15 @@ const StyledEditButtonContainer = styled(motion.div)`
right: 5px; right: 5px;
`; `;
type TableCellButtonProps = { type RecordTableCellEditButtonProps = {
onClick?: () => void; onClick?: () => void;
Icon: IconComponent; Icon: IconComponent;
}; };
export const TableCellButton = ({ onClick, Icon }: TableCellButtonProps) => ( export const RecordTableCellEditButton = ({
onClick,
Icon,
}: RecordTableCellEditButtonProps) => (
<StyledEditButtonContainer <StyledEditButtonContainer
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
animate={{ opacity: 1 }} animate={{ opacity: 1 }}

View File

@ -1,7 +1,7 @@
import { ReactElement } from 'react'; import { ReactElement } from 'react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
const StyledEditableCellEditModeContainer = styled.div<TableCellEditModeProps>` const StyledEditableCellEditModeContainer = styled.div<RecordTableCellEditModeProps>`
align-items: center; align-items: center;
display: flex; display: flex;
min-width: 200px; min-width: 200px;
@ -9,7 +9,7 @@ const StyledEditableCellEditModeContainer = styled.div<TableCellEditModeProps>`
z-index: 1; z-index: 1;
`; `;
export type TableCellEditModeProps = { export type RecordTableCellEditModeProps = {
children: ReactElement; children: ReactElement;
transparent?: boolean; transparent?: boolean;
maxContentWidth?: number; maxContentWidth?: number;
@ -18,11 +18,11 @@ export type TableCellEditModeProps = {
initialValue?: string; initialValue?: string;
}; };
export const TableCellEditMode = ({ export const RecordTableCellEditMode = ({
editModeHorizontalAlign, editModeHorizontalAlign,
editModeVerticalPosition, editModeVerticalPosition,
children, children,
}: TableCellEditModeProps) => ( }: RecordTableCellEditModeProps) => (
<StyledEditableCellEditModeContainer <StyledEditableCellEditModeContainer
data-testid="editable-cell-edit-mode-container" data-testid="editable-cell-edit-mode-container"
editModeHorizontalAlign={editModeHorizontalAlign} editModeHorizontalAlign={editModeHorizontalAlign}

View File

@ -9,13 +9,13 @@ import { isNonTextWritingKey } from '@/ui/utilities/hotkey/utils/isNonTextWritin
import { TableHotkeyScope } from '../../types/TableHotkeyScope'; import { TableHotkeyScope } from '../../types/TableHotkeyScope';
import { useTableCell } from '../hooks/useTableCell'; import { useTableCell } from '../hooks/useTableCell';
import { TableCellDisplayContainer } from './RecordTableCellDisplayContainer'; import { RecordTableCellDisplayContainer } from './RecordTableCellDisplayContainer';
type TableCellSoftFocusModeProps = PropsWithChildren<unknown>; type RecordTableCellSoftFocusModeProps = PropsWithChildren<unknown>;
export const TableCellSoftFocusMode = ({ export const RecordTableCellSoftFocusMode = ({
children, children,
}: TableCellSoftFocusModeProps) => { }: RecordTableCellSoftFocusModeProps) => {
const { openTableCell } = useTableCell(); const { openTableCell } = useTableCell();
const isFieldInputOnly = useIsFieldInputOnly(); const isFieldInputOnly = useIsFieldInputOnly();
@ -95,12 +95,12 @@ export const TableCellSoftFocusMode = ({
}; };
return ( return (
<TableCellDisplayContainer <RecordTableCellDisplayContainer
onClick={handleClick} onClick={handleClick}
softFocus softFocus
scrollRef={scrollRef} scrollRef={scrollRef}
> >
{children} {children}
</TableCellDisplayContainer> </RecordTableCellDisplayContainer>
); );
}; };

View File

@ -1,16 +1,30 @@
import { useCallback } from 'react'; import { useCallback } from 'react';
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { useMoveEditModeToTableCellPosition } from '../../hooks/internal/useMoveEditModeToCellPosition'; import { useMoveEditModeToTableCellPosition } from '../../hooks/internal/useMoveEditModeToCellPosition';
import { isTableCellInEditModeFamilyState } from '../../states/isTableCellInEditModeFamilyState';
import { useCurrentTableCellPosition } from './useCurrentCellPosition'; import { useCurrentTableCellPosition } from './useCurrentCellPosition';
export const useCurrentTableCellEditMode = () => { export const useCurrentTableCellEditMode = () => {
const moveEditModeToTableCellPosition = useMoveEditModeToTableCellPosition(); const { scopeId } = useRecordTable();
const moveEditModeToTableCellPosition =
useMoveEditModeToTableCellPosition(scopeId);
const currentTableCellPosition = useCurrentTableCellPosition(); const currentTableCellPosition = useCurrentTableCellPosition();
const { isTableCellInEditModeScopeInjector } = getRecordTableScopeInjector();
const { injectFamilyStateWithRecordTableScopeId } =
useRecordTableScopedStates();
const isTableCellInEditModeFamilyState =
injectFamilyStateWithRecordTableScopeId(isTableCellInEditModeScopeInjector);
const [isCurrentTableCellInEditMode] = useRecoilState( const [isCurrentTableCellInEditMode] = useRecoilState(
isTableCellInEditModeFamilyState(currentTableCellPosition), isTableCellInEditModeFamilyState(currentTableCellPosition),
); );

View File

@ -1,14 +1,24 @@
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { isSoftFocusOnTableCellFamilyState } from '../../states/isSoftFocusOnTableCellFamilyState'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { useCurrentTableCellPosition } from './useCurrentCellPosition'; import { useCurrentTableCellPosition } from './useCurrentCellPosition';
export const useIsSoftFocusOnCurrentTableCell = () => { export const useIsSoftFocusOnCurrentTableCell = () => {
const currentTableCellPosition = useCurrentTableCellPosition(); const currentTableCellPosition = useCurrentTableCellPosition();
const { isSoftFocusOnTableCellScopeInjector } = getRecordTableScopeInjector();
const { injectFamilyStateWithRecordTableScopeId } =
useRecordTableScopedStates();
const isSoftFocusActiveFamilyState = injectFamilyStateWithRecordTableScopeId(
isSoftFocusOnTableCellScopeInjector,
);
const isSoftFocusOnTableCell = useRecoilValue( const isSoftFocusOnTableCell = useRecoilValue(
isSoftFocusOnTableCellFamilyState(currentTableCellPosition), isSoftFocusActiveFamilyState(currentTableCellPosition),
); );
return isSoftFocusOnTableCell; return isSoftFocusOnTableCell;

View File

@ -1,9 +1,9 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState'; import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState';
import { currentTableCellInEditModePositionState } from '../../states/currentTableCellInEditModePositionState';
import { isTableCellInEditModeFamilyState } from '../../states/isTableCellInEditModeFamilyState';
import { TableHotkeyScope } from '../../types/TableHotkeyScope'; import { TableHotkeyScope } from '../../types/TableHotkeyScope';
import { useSetSoftFocusOnCurrentTableCell } from './useSetSoftFocusOnCurrentTableCell'; import { useSetSoftFocusOnCurrentTableCell } from './useSetSoftFocusOnCurrentTableCell';
@ -11,12 +11,27 @@ import { useSetSoftFocusOnCurrentTableCell } from './useSetSoftFocusOnCurrentTab
export const useMoveSoftFocusToCurrentCellOnHover = () => { export const useMoveSoftFocusToCurrentCellOnHover = () => {
const setSoftFocusOnCurrentTableCell = useSetSoftFocusOnCurrentTableCell(); const setSoftFocusOnCurrentTableCell = useSetSoftFocusOnCurrentTableCell();
const {
currentTableCellInEditModePositionScopeInjector,
isTableCellInEditModeScopeInjector,
} = getRecordTableScopeInjector();
const {
injectSnapshotValueWithRecordTableScopeId,
injectFamilyStateWithRecordTableScopeId,
} = useRecordTableScopedStates();
const isTableCellInEditModeFamilyState =
injectFamilyStateWithRecordTableScopeId(isTableCellInEditModeScopeInjector);
return useRecoilCallback( return useRecoilCallback(
({ snapshot }) => ({ snapshot }) =>
() => { () => {
const currentTableCellInEditModePosition = snapshot const currentTableCellInEditModePosition =
.getLoadable(currentTableCellInEditModePositionState) injectSnapshotValueWithRecordTableScopeId(
.valueOrThrow(); snapshot,
currentTableCellInEditModePositionScopeInjector,
);
const isSomeCellInEditMode = snapshot.getLoadable( const isSomeCellInEditMode = snapshot.getLoadable(
isTableCellInEditModeFamilyState(currentTableCellInEditModePosition), isTableCellInEditModeFamilyState(currentTableCellInEditModePosition),
@ -38,6 +53,11 @@ export const useMoveSoftFocusToCurrentCellOnHover = () => {
setSoftFocusOnCurrentTableCell(); setSoftFocusOnCurrentTableCell();
} }
}, },
[setSoftFocusOnCurrentTableCell], [
currentTableCellInEditModePositionScopeInjector,
injectSnapshotValueWithRecordTableScopeId,
isTableCellInEditModeFamilyState,
setSoftFocusOnCurrentTableCell,
],
); );
}; };

View File

@ -1,15 +1,24 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
import { useSetSoftFocusPosition } from '../../hooks/internal/useSetSoftFocusPosition';
import { isSoftFocusActiveState } from '../../states/isSoftFocusActiveState';
import { TableHotkeyScope } from '../../types/TableHotkeyScope'; import { TableHotkeyScope } from '../../types/TableHotkeyScope';
import { useCurrentTableCellPosition } from './useCurrentCellPosition'; import { useCurrentTableCellPosition } from './useCurrentCellPosition';
export const useSetSoftFocusOnCurrentTableCell = () => { export const useSetSoftFocusOnCurrentTableCell = () => {
const setSoftFocusPosition = useSetSoftFocusPosition(); const { setSoftFocusPosition } = useRecordTable();
const { isSoftFocusActiveScopeInjector } = getRecordTableScopeInjector();
const { injectStateWithRecordTableScopeId } = useRecordTableScopedStates();
const isSoftFocusActiveState = injectStateWithRecordTableScopeId(
isSoftFocusActiveScopeInjector,
);
const currentTableCellPosition = useCurrentTableCellPosition(); const currentTableCellPosition = useCurrentTableCellPosition();
@ -24,6 +33,11 @@ export const useSetSoftFocusOnCurrentTableCell = () => {
setHotkeyScope(TableHotkeyScope.TableSoftFocus); setHotkeyScope(TableHotkeyScope.TableSoftFocus);
}, },
[setHotkeyScope, currentTableCellPosition, setSoftFocusPosition], [
setSoftFocusPosition,
currentTableCellPosition,
isSoftFocusActiveState,
setHotkeyScope,
],
); );
}; };

View File

@ -7,6 +7,8 @@ import { useIsFieldEmpty } from '@/object-record/field/hooks/useIsFieldEmpty';
import { entityFieldInitialValueFamilyState } from '@/object-record/field/states/entityFieldInitialValueFamilyState'; import { entityFieldInitialValueFamilyState } from '@/object-record/field/states/entityFieldInitialValueFamilyState';
import { FieldInitialValue } from '@/object-record/field/types/FieldInitialValue'; import { FieldInitialValue } from '@/object-record/field/types/FieldInitialValue';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates'; import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { useDragSelect } from '@/ui/utilities/drag-select/hooks/useDragSelect'; import { useDragSelect } from '@/ui/utilities/drag-select/hooks/useDragSelect';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
@ -23,9 +25,15 @@ const DEFAULT_CELL_SCOPE: HotkeyScope = {
}; };
export const useTableCell = () => { export const useTableCell = () => {
const { objectMetadataConfigState } = useRecordTableScopedStates(); const { scopeId: recordTableScopeId } = useRecordTable();
const objectMetadataConfig = useRecoilValue(objectMetadataConfigState); const { objectMetadataConfigScopeInjector } = getRecordTableScopeInjector();
const { injectStateWithRecordTableScopeId } = useRecordTableScopedStates();
const objectMetadataConfig = useRecoilValue(
injectStateWithRecordTableScopeId(objectMetadataConfigScopeInjector),
);
const basePathToShowPage = objectMetadataConfig?.basePathToShowPage; const basePathToShowPage = objectMetadataConfig?.basePathToShowPage;
@ -33,7 +41,8 @@ export const useTableCell = () => {
const setHotkeyScope = useSetHotkeyScope(); const setHotkeyScope = useSetHotkeyScope();
const { setDragSelectionStartEnabled } = useDragSelect(); const { setDragSelectionStartEnabled } = useDragSelect();
const closeCurrentTableCellInEditMode = useCloseCurrentTableCellInEditMode(); const closeCurrentTableCellInEditMode =
useCloseCurrentTableCellInEditMode(recordTableScopeId);
const customCellHotkeyScope = useContext(CellHotkeyScopeContext); const customCellHotkeyScope = useContext(CellHotkeyScopeContext);

View File

@ -1,13 +1,26 @@
import { useContext } from 'react'; import { useContext } from 'react';
import { useRecoilCallback, useRecoilState } from 'recoil'; import { useRecoilCallback, useRecoilValue } from 'recoil';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { RowIdContext } from '../../contexts/RowIdContext'; import { RowIdContext } from '../../contexts/RowIdContext';
import { isRowSelectedFamilyState } from '../states/isRowSelectedFamilyState';
export const useCurrentRowSelected = () => { export const useCurrentRowSelected = () => {
const currentRowId = useContext(RowIdContext); const currentRowId = useContext(RowIdContext);
const [isRowSelected] = useRecoilState( const { isRowSelectedScopeInjector } = getRecordTableScopeInjector();
const {
injectFamilyStateWithRecordTableScopeId,
injectFamilySnapshotValueWithRecordTableScopeId,
} = useRecordTableScopedStates();
const isRowSelectedFamilyState = injectFamilyStateWithRecordTableScopeId(
isRowSelectedScopeInjector,
);
const isRowSelected = useRecoilValue(
isRowSelectedFamilyState(currentRowId ?? ''), isRowSelectedFamilyState(currentRowId ?? ''),
); );
@ -16,9 +29,10 @@ export const useCurrentRowSelected = () => {
(newSelectedState: boolean) => { (newSelectedState: boolean) => {
if (!currentRowId) return; if (!currentRowId) return;
const isRowSelected = snapshot const isRowSelected = injectFamilySnapshotValueWithRecordTableScopeId(
.getLoadable(isRowSelectedFamilyState(currentRowId)) snapshot,
.valueOrThrow(); isRowSelectedScopeInjector,
)(currentRowId);
if (newSelectedState && !isRowSelected) { if (newSelectedState && !isRowSelected) {
set(isRowSelectedFamilyState(currentRowId), true); set(isRowSelectedFamilyState(currentRowId), true);
@ -26,7 +40,12 @@ export const useCurrentRowSelected = () => {
set(isRowSelectedFamilyState(currentRowId), false); set(isRowSelectedFamilyState(currentRowId), false);
} }
}, },
[currentRowId], [
currentRowId,
injectFamilySnapshotValueWithRecordTableScopeId,
isRowSelectedFamilyState,
isRowSelectedScopeInjector,
],
); );
return { return {

View File

@ -1,6 +0,0 @@
import { atomFamily } from 'recoil';
export const isRowSelectedFamilyState = atomFamily<boolean, string>({
key: 'isRowSelectedFamilyState',
default: false,
});

View File

@ -0,0 +1,9 @@
import { createScopedFamilyState } from '@/ui/utilities/recoil-scope/utils/createScopedFamilyState';
export const isRowSelectedScopedFamilyState = createScopedFamilyState<
boolean,
string
>({
key: 'isRowSelectedFamilyState',
defaultValue: false,
});

View File

@ -1,8 +1,8 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useSetRecoilState } from 'recoil';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { FieldMetadata } from '../../field/types/FieldMetadata'; import { FieldMetadata } from '../../field/types/FieldMetadata';
import { useRecordTableScopedStates } from '../hooks/internal/useRecordTableScopedStates';
import { ColumnDefinition } from '../types/ColumnDefinition'; import { ColumnDefinition } from '../types/ColumnDefinition';
type RecordTableScopeInitEffectProps = { type RecordTableScopeInitEffectProps = {
@ -13,9 +13,7 @@ type RecordTableScopeInitEffectProps = {
export const RecordTableScopeInitEffect = ({ export const RecordTableScopeInitEffect = ({
onColumnsChange, onColumnsChange,
}: RecordTableScopeInitEffectProps) => { }: RecordTableScopeInitEffectProps) => {
const { onColumnsChangeState } = useRecordTableScopedStates(); const { setOnColumnsChange } = useRecordTable();
const setOnColumnsChange = useSetRecoilState(onColumnsChangeState);
useEffect(() => { useEffect(() => {
setOnColumnsChange(() => onColumnsChange); setOnColumnsChange(() => onColumnsChange);

View File

@ -0,0 +1,12 @@
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
import { TableCellPosition } from '../types/TableCellPosition';
export const currentTableCellInEditModePositionScopedState =
createScopedState<TableCellPosition>({
key: 'currentTableCellInEditModePositionScopedState',
defaultValue: {
row: 0,
column: 1,
},
});

View File

@ -1,11 +0,0 @@
import { atom } from 'recoil';
import { TableCellPosition } from '../types/TableCellPosition';
export const currentTableCellInEditModePositionState = atom<TableCellPosition>({
key: 'currentTableCellInEditModePositionState',
default: {
row: 0,
column: 1,
},
});

View File

@ -0,0 +1,7 @@
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
export const isRecordTableInitialLoadingScopedState =
createScopedState<boolean>({
key: 'isRecordTableInitialLoadingScopedState',
defaultValue: true,
});

View File

@ -1,6 +0,0 @@
import { atom } from 'recoil';
export const isRecordTableInitialLoadingState = atom<boolean>({
key: 'isRecordTableInitialLoadingState',
default: true,
});

View File

@ -0,0 +1,6 @@
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
export const isSoftFocusActiveScopedState = createScopedState<boolean>({
key: 'isSoftFocusActiveScopedState',
defaultValue: false,
});

View File

@ -1,6 +0,0 @@
import { atom } from 'recoil';
export const isSoftFocusActiveState = atom<boolean>({
key: 'isSoftFocusActiveState',
default: false,
});

View File

@ -1,11 +0,0 @@
import { atomFamily } from 'recoil';
import { TableCellPosition } from '../types/TableCellPosition';
export const isSoftFocusOnTableCellFamilyState = atomFamily<
boolean,
TableCellPosition
>({
key: 'isSoftFocusOnTableCellFamilyState',
default: false,
});

View File

@ -0,0 +1,11 @@
import { createScopedFamilyState } from '@/ui/utilities/recoil-scope/utils/createScopedFamilyState';
import { TableCellPosition } from '../types/TableCellPosition';
export const isSoftFocusOnTableCellScopedFamilyState = createScopedFamilyState<
boolean,
TableCellPosition
>({
key: 'isSoftFocusOnTableCellScopedFamilyState',
defaultValue: false,
});

View File

@ -1,11 +0,0 @@
import { atomFamily } from 'recoil';
import { TableCellPosition } from '../types/TableCellPosition';
export const isTableCellInEditModeFamilyState = atomFamily<
boolean,
TableCellPosition
>({
key: 'isTableCellInEditModeFamilyState',
default: false,
});

View File

@ -0,0 +1,11 @@
import { createScopedFamilyState } from '@/ui/utilities/recoil-scope/utils/createScopedFamilyState';
import { TableCellPosition } from '../types/TableCellPosition';
export const isTableCellInEditModeScopedFamilyState = createScopedFamilyState<
boolean,
TableCellPosition
>({
key: 'isTableCellInEditModeScopedFamilyState',
defaultValue: false,
});

View File

@ -0,0 +1,6 @@
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
export const numberOfTableRowsScopedState = createScopedState<number>({
key: 'numberOfTableRowsScopedState',
defaultValue: 0,
});

View File

@ -1,6 +0,0 @@
import { atom } from 'recoil';
export const numberOfTableRowsState = atom<number>({
key: 'numberOfTableRowsState',
default: 0,
});

View File

@ -0,0 +1,6 @@
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
export const resizeFieldOffsetScopedState = createScopedState<number>({
key: 'resizeFieldOffsetScopedState',
defaultValue: 0,
});

View File

@ -1,6 +0,0 @@
import { atom } from 'recoil';
export const resizeFieldOffsetState = atom<number>({
key: 'resizeFieldOffsetState',
default: 0,
});

View File

@ -0,0 +1,29 @@
import { createScopedSelector } from '@/ui/utilities/recoil-scope/utils/createScopedSelector';
import { AllRowsSelectedStatus } from '../../types/AllRowSelectedStatus';
import { numberOfTableRowsScopedState } from '../numberOfTableRowsScopedState';
import { selectedRowIdsScopedSelector } from './selectedRowIdsScopedSelector';
export const allRowsSelectedStatusScopedSelector =
createScopedSelector<AllRowsSelectedStatus>({
key: 'allRowsSelectedStatusScopedSelector',
get:
({ scopeId }) =>
({ get }) => {
const numberOfRows = get(numberOfTableRowsScopedState({ scopeId }));
const selectedRowIds = get(selectedRowIdsScopedSelector({ scopeId }));
const numberOfSelectedRows = selectedRowIds.length;
const allRowsSelectedStatus =
numberOfSelectedRows === 0
? 'none'
: numberOfRows === numberOfSelectedRows
? 'all'
: 'some';
return allRowsSelectedStatus;
},
});

View File

@ -1,26 +0,0 @@
import { selector } from 'recoil';
import { AllRowsSelectedStatus } from '../../types/AllRowSelectedStatus';
import { numberOfTableRowsState } from '../numberOfTableRowsState';
import { selectedRowIdsSelector } from './selectedRowIdsSelector';
export const allRowsSelectedStatusSelector = selector<AllRowsSelectedStatus>({
key: 'allRowsSelectedStatusSelector',
get: ({ get }) => {
const numberOfRows = get(numberOfTableRowsState);
const selectedRowIds = get(selectedRowIdsSelector);
const numberOfSelectedRows = selectedRowIds.length;
const allRowsSelectedStatus =
numberOfSelectedRows === 0
? 'none'
: numberOfRows === numberOfSelectedRows
? 'all'
: 'some';
return allRowsSelectedStatus;
},
});

View File

@ -1,12 +1,12 @@
import { selectorFamily } from 'recoil'; import { createScopedSelector } from '@/ui/utilities/recoil-scope/utils/createScopedSelector';
import { availableTableColumnsScopedState } from '../availableTableColumnsScopedState'; import { availableTableColumnsScopedState } from '../availableTableColumnsScopedState';
import { tableColumnsScopedState } from '../tableColumnsScopedState'; import { tableColumnsScopedState } from '../tableColumnsScopedState';
export const hiddenTableColumnsScopedSelector = selectorFamily({ export const hiddenTableColumnsScopedSelector = createScopedSelector({
key: 'hiddenTableColumnsScopedSelector', key: 'hiddenTableColumnsScopedSelector',
get: get:
(scopeId: string) => ({ scopeId }) =>
({ get }) => { ({ get }) => {
const columns = get(tableColumnsScopedState({ scopeId })); const columns = get(tableColumnsScopedState({ scopeId }));
const columnKeys = columns.map(({ fieldMetadataId }) => fieldMetadataId); const columnKeys = columns.map(({ fieldMetadataId }) => fieldMetadataId);

View File

@ -1,11 +1,11 @@
import { selectorFamily } from 'recoil'; import { createScopedSelector } from '@/ui/utilities/recoil-scope/utils/createScopedSelector';
import { tableColumnsScopedState } from '../tableColumnsScopedState'; import { tableColumnsScopedState } from '../tableColumnsScopedState';
export const numberOfTableColumnsScopedSelector = selectorFamily({ export const numberOfTableColumnsScopedSelector = createScopedSelector({
key: 'numberOfTableColumnsScopedSelector', key: 'numberOfTableColumnsScopedSelector',
get: get:
(scopeId: string) => ({ scopeId }) =>
({ get }) => ({ get }) =>
get(tableColumnsScopedState({ scopeId })).length, get(tableColumnsScopedState({ scopeId })).length,
}); });

View File

@ -0,0 +1,23 @@
import { createScopedSelector } from '@/ui/utilities/recoil-scope/utils/createScopedSelector';
import { isRowSelectedScopedFamilyState } from '../../record-table-row/states/isRowSelectedScopedFamilyState';
import { tableRowIdsScopedState } from '../tableRowIdsScopedState';
export const selectedRowIdsScopedSelector = createScopedSelector<string[]>({
key: 'selectedRowIdsScopedSelector',
get:
({ scopeId }) =>
({ get }) => {
const rowIds = get(tableRowIdsScopedState({ scopeId }));
return rowIds.filter(
(rowId) =>
get(
isRowSelectedScopedFamilyState({
scopeId,
familyKey: rowId,
}),
) === true,
);
},
});

View File

@ -1,15 +0,0 @@
import { selector } from 'recoil';
import { isRowSelectedFamilyState } from '../../record-table-row/states/isRowSelectedFamilyState';
import { tableRowIdsState } from '../tableRowIdsState';
export const selectedRowIdsSelector = selector<string[]>({
key: 'selectedRowIdsSelector',
get: ({ get }) => {
const rowIds = get(tableRowIdsState);
return rowIds.filter(
(rowId) => get(isRowSelectedFamilyState(rowId)) === true,
);
},
});

View File

@ -1,14 +1,13 @@
import { selectorFamily } from 'recoil';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata'; import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { createScopedSelector } from '@/ui/utilities/recoil-scope/utils/createScopedSelector';
import { ColumnDefinition } from '../../types/ColumnDefinition'; import { ColumnDefinition } from '../../types/ColumnDefinition';
import { tableColumnsScopedState } from '../tableColumnsScopedState'; import { tableColumnsScopedState } from '../tableColumnsScopedState';
export const tableColumnsByKeyScopedSelector = selectorFamily({ export const tableColumnsByKeyScopedSelector = createScopedSelector({
key: 'tableColumnsByKeyScopedSelector', key: 'tableColumnsByKeyScopedSelector',
get: get:
(scopeId: string) => ({ scopeId }) =>
({ get }) => ({ get }) =>
get(tableColumnsScopedState({ scopeId })).reduce< get(tableColumnsScopedState({ scopeId })).reduce<
Record<string, ColumnDefinition<FieldMetadata>> Record<string, ColumnDefinition<FieldMetadata>>

View File

@ -1,12 +1,12 @@
import { selectorFamily } from 'recoil'; import { createScopedSelector } from '@/ui/utilities/recoil-scope/utils/createScopedSelector';
import { availableTableColumnsScopedState } from '../availableTableColumnsScopedState'; import { availableTableColumnsScopedState } from '../availableTableColumnsScopedState';
import { tableColumnsScopedState } from '../tableColumnsScopedState'; import { tableColumnsScopedState } from '../tableColumnsScopedState';
export const visibleTableColumnsScopedSelector = selectorFamily({ export const visibleTableColumnsScopedSelector = createScopedSelector({
key: 'visibleTableColumnsScopedSelector', key: 'visibleTableColumnsScopedSelector',
get: get:
(scopeId: string) => ({ scopeId }) =>
({ get }) => { ({ get }) => {
const columns = get(tableColumnsScopedState({ scopeId })); const columns = get(tableColumnsScopedState({ scopeId }));
const availableColumnKeys = get( const availableColumnKeys = get(

View File

@ -0,0 +1,12 @@
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
import { TableCellPosition } from '../types/TableCellPosition';
export const softFocusPositionScopedState =
createScopedState<TableCellPosition>({
key: 'softFocusPositionScopedState',
defaultValue: {
row: 0,
column: 1,
},
});

View File

@ -1,11 +0,0 @@
import { atom } from 'recoil';
import { TableCellPosition } from '../types/TableCellPosition';
export const softFocusPositionState = atom<TableCellPosition>({
key: 'softFocusPositionState',
default: {
row: 0,
column: 1,
},
});

View File

@ -0,0 +1,6 @@
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
export const tableRowIdsScopedState = createScopedState<string[]>({
key: 'tableRowIdsScopedState',
defaultValue: [],
});

View File

@ -1,6 +0,0 @@
import { atom } from 'recoil';
export const tableRowIdsState = atom<string[]>({
key: 'tableRowIdsState',
default: [],
});

View File

@ -0,0 +1,145 @@
import { isRowSelectedScopedFamilyState } from '@/object-record/record-table/record-table-row/states/isRowSelectedScopedFamilyState';
import { currentTableCellInEditModePositionScopedState } from '@/object-record/record-table/states/currentTableCellInEditModePositionScopedState';
import { isRecordTableInitialLoadingScopedState } from '@/object-record/record-table/states/isRecordTableInitialLoadingScopedState';
import { isSoftFocusActiveScopedState } from '@/object-record/record-table/states/isSoftFocusActiveScopedState';
import { isSoftFocusOnTableCellScopedFamilyState } from '@/object-record/record-table/states/isSoftFocusOnTableCellScopedFamilyState';
import { isTableCellInEditModeScopedFamilyState } from '@/object-record/record-table/states/isTableCellInEditModeScopedFamilyState';
import { numberOfTableRowsScopedState } from '@/object-record/record-table/states/numberOfTableRowsScopedState';
import { objectMetadataConfigScopedState } from '@/object-record/record-table/states/objectMetadataConfigScopedState';
import { resizeFieldOffsetScopedState } from '@/object-record/record-table/states/resizeFieldOffsetScopedState';
import { allRowsSelectedStatusScopedSelector } from '@/object-record/record-table/states/selectors/allRowsSelectedStatusScopedSelector';
import { numberOfTableColumnsScopedSelector } from '@/object-record/record-table/states/selectors/numberOfTableColumnsScopedSelector';
import { selectedRowIdsScopedSelector } from '@/object-record/record-table/states/selectors/selectedRowIdsScopedSelector';
import { softFocusPositionScopedState } from '@/object-record/record-table/states/softFocusPositionScopedState';
import { tableLastRowVisibleScopedState } from '@/object-record/record-table/states/tableLastRowVisibleScopedState';
import { tableRowIdsScopedState } from '@/object-record/record-table/states/tableRowIdsScopedState';
import { getFamilyScopeInjector } from '@/ui/utilities/recoil-scope/utils/getFamilyScopeInjector';
import { getScopeInjector } from '@/ui/utilities/recoil-scope/utils/getScopeInjector';
import { getSelectorScopeInjector } from '@/ui/utilities/recoil-scope/utils/getSelectorScopeInjector';
import { availableTableColumnsScopedState } from '../states/availableTableColumnsScopedState';
import { onColumnsChangeScopedState } from '../states/onColumnsChangeScopedState';
import { onEntityCountChangeScopedState } from '../states/onEntityCountChangeScopedState';
import { hiddenTableColumnsScopedSelector } from '../states/selectors/hiddenTableColumnsScopedSelector';
import { tableColumnsByKeyScopedSelector } from '../states/selectors/tableColumnsByKeyScopedSelector';
import { visibleTableColumnsScopedSelector } from '../states/selectors/visibleTableColumnsScopedSelector';
import { tableColumnsScopedState } from '../states/tableColumnsScopedState';
import { tableFiltersScopedState } from '../states/tableFiltersScopedState';
import { tableSortsScopedState } from '../states/tableSortsScopedState';
export const getRecordTableScopeInjector = () => {
const availableTableColumnsScopeInjector = getScopeInjector(
availableTableColumnsScopedState,
);
const tableFiltersScopeInjector = getScopeInjector(tableFiltersScopedState);
const tableSortsScopeInjector = getScopeInjector(tableSortsScopedState);
const tableColumnsScopeInjector = getScopeInjector(tableColumnsScopedState);
const objectMetadataConfigScopeInjector = getScopeInjector(
objectMetadataConfigScopedState,
);
const tableColumnsByKeyScopeInjector = getSelectorScopeInjector(
tableColumnsByKeyScopedSelector,
);
const hiddenTableColumnsScopeInjector = getSelectorScopeInjector(
hiddenTableColumnsScopedSelector,
);
const visibleTableColumnsScopeInjector = getSelectorScopeInjector(
visibleTableColumnsScopedSelector,
);
const onColumnsChangeScopeInjector = getScopeInjector(
onColumnsChangeScopedState,
);
const onEntityCountScopeInjector = getScopeInjector(
onEntityCountChangeScopedState,
);
const tableLastRowVisibleScopeInjector = getScopeInjector(
tableLastRowVisibleScopedState,
);
const softFocusPositionScopeInjector = getScopeInjector(
softFocusPositionScopedState,
);
const numberOfTableRowsScopeInjector = getScopeInjector(
numberOfTableRowsScopedState,
);
const numberOfTableColumnsScopeInjector = getSelectorScopeInjector(
numberOfTableColumnsScopedSelector,
);
const currentTableCellInEditModePositionScopeInjector = getScopeInjector(
currentTableCellInEditModePositionScopedState,
);
const isTableCellInEditModeScopeInjector = getFamilyScopeInjector(
isTableCellInEditModeScopedFamilyState,
);
const isSoftFocusActiveScopeInjector = getScopeInjector(
isSoftFocusActiveScopedState,
);
const isSoftFocusOnTableCellScopeInjector = getFamilyScopeInjector(
isSoftFocusOnTableCellScopedFamilyState,
);
const tableRowIdsScopeInjector = getScopeInjector(tableRowIdsScopedState);
const isRowSelectedScopeInjector = getFamilyScopeInjector(
isRowSelectedScopedFamilyState,
);
const allRowsSelectedStatusScopeInjector = getSelectorScopeInjector(
allRowsSelectedStatusScopedSelector,
);
const selectedRowIdsScopeInjector = getSelectorScopeInjector(
selectedRowIdsScopedSelector,
);
const isRecordTableInitialLoadingScopeInjector = getScopeInjector(
isRecordTableInitialLoadingScopedState,
);
const resizeFieldOffsetScopeInjector = getScopeInjector(
resizeFieldOffsetScopedState,
);
return {
availableTableColumnsScopeInjector,
tableFiltersScopeInjector,
tableSortsScopeInjector,
tableColumnsScopeInjector,
objectMetadataConfigScopeInjector,
tableColumnsByKeyScopeInjector,
hiddenTableColumnsScopeInjector,
visibleTableColumnsScopeInjector,
onColumnsChangeScopeInjector,
onEntityCountScopeInjector,
tableLastRowVisibleScopeInjector,
softFocusPositionScopeInjector,
numberOfTableRowsScopeInjector,
numberOfTableColumnsScopeInjector,
currentTableCellInEditModePositionScopeInjector,
isTableCellInEditModeScopeInjector,
isSoftFocusActiveScopeInjector,
isSoftFocusOnTableCellScopeInjector,
tableRowIdsScopeInjector,
isRowSelectedScopeInjector,
allRowsSelectedStatusScopeInjector,
selectedRowIdsScopeInjector,
isRecordTableInitialLoadingScopeInjector,
resizeFieldOffsetScopeInjector,
};
};

View File

@ -1,82 +0,0 @@
import { objectMetadataConfigScopedState } from '@/object-record/record-table/states/objectMetadataConfigScopedState';
import { tableLastRowVisibleScopedState } from '@/object-record/record-table/states/tableLastRowVisibleScopedState';
import { getScopedStateDeprecated } from '@/ui/utilities/recoil-scope/utils/getScopedStateDeprecated';
import { availableTableColumnsScopedState } from '../states/availableTableColumnsScopedState';
import { onColumnsChangeScopedState } from '../states/onColumnsChangeScopedState';
import { onEntityCountChangeScopedState } from '../states/onEntityCountChange';
import { hiddenTableColumnsScopedSelector } from '../states/selectors/hiddenTableColumnsScopedSelector';
import { tableColumnsByKeyScopedSelector } from '../states/selectors/tableColumnsByKeyScopedSelector';
import { visibleTableColumnsScopedSelector } from '../states/selectors/visibleTableColumnsScopedSelector';
import { tableColumnsScopedState } from '../states/tableColumnsScopedState';
import { tableFiltersScopedState } from '../states/tableFiltersScopedState';
import { tableSortsScopedState } from '../states/tableSortsScopedState';
export const getRecordTableScopedStates = ({
recordTableScopeId,
}: {
recordTableScopeId: string;
}) => {
const availableTableColumnsState = getScopedStateDeprecated(
availableTableColumnsScopedState,
recordTableScopeId,
);
const tableFiltersState = getScopedStateDeprecated(
tableFiltersScopedState,
recordTableScopeId,
);
const tableSortsState = getScopedStateDeprecated(
tableSortsScopedState,
recordTableScopeId,
);
const tableColumnsState = getScopedStateDeprecated(
tableColumnsScopedState,
recordTableScopeId,
);
const objectMetadataConfigState = getScopedStateDeprecated(
objectMetadataConfigScopedState,
recordTableScopeId,
);
const tableColumnsByKeySelector =
tableColumnsByKeyScopedSelector(recordTableScopeId);
const hiddenTableColumnsSelector =
hiddenTableColumnsScopedSelector(recordTableScopeId);
const visibleTableColumnsSelector =
visibleTableColumnsScopedSelector(recordTableScopeId);
const onColumnsChangeState = getScopedStateDeprecated(
onColumnsChangeScopedState,
recordTableScopeId,
);
const onEntityCountChangeState = getScopedStateDeprecated(
onEntityCountChangeScopedState,
recordTableScopeId,
);
const tableLastRowVisibleState = getScopedStateDeprecated(
tableLastRowVisibleScopedState,
recordTableScopeId,
);
return {
availableTableColumnsState,
tableFiltersState,
tableSortsState,
tableColumnsState,
objectMetadataConfigState,
tableColumnsByKeySelector,
hiddenTableColumnsSelector,
visibleTableColumnsSelector,
onColumnsChangeState,
onEntityCountChangeState,
tableLastRowVisibleState,
};
};

View File

@ -14,9 +14,9 @@ import { logError } from '~/utils/logError';
export const PipelineAddButton = () => { export const PipelineAddButton = () => {
const { enqueueSnackBar } = useSnackBar(); const { enqueueSnackBar } = useSnackBar();
const { closeDropdown, toggleDropdown } = useDropdown({ const { closeDropdown, toggleDropdown } = useDropdown(
dropdownScopeId: 'add-pipeline-progress', 'add-pipeline-progress',
}); );
const createOpportunity = useCreateOpportunity(); const createOpportunity = useCreateOpportunity();

View File

@ -24,7 +24,7 @@ export const SettingsAccountsRowDropdownMenu = ({
const dropdownScopeId = `settings-account-row-${account.uuid}`; const dropdownScopeId = `settings-account-row-${account.uuid}`;
const navigate = useNavigate(); const navigate = useNavigate();
const { closeDropdown } = useDropdown({ dropdownScopeId }); const { closeDropdown } = useDropdown(dropdownScopeId);
return ( return (
<DropdownScope dropdownScopeId={dropdownScopeId}> <DropdownScope dropdownScopeId={dropdownScopeId}>

View File

@ -68,12 +68,12 @@ export const SettingsObjectFieldSelectFormOptionRow = ({
return { color: `${baseScopeId}-color`, actions: `${baseScopeId}-actions` }; return { color: `${baseScopeId}-color`, actions: `${baseScopeId}-actions` };
}, []); }, []);
const { closeDropdown: closeColorDropdown } = useDropdown({ const { closeDropdown: closeColorDropdown } = useDropdown(
dropdownScopeId: dropdownScopeIds.color, dropdownScopeIds.color,
}); );
const { closeDropdown: closeActionsDropdown } = useDropdown({ const { closeDropdown: closeActionsDropdown } = useDropdown(
dropdownScopeId: dropdownScopeIds.actions, dropdownScopeIds.actions,
}); );
return ( return (
<StyledRow className={className}> <StyledRow className={className}>

View File

@ -57,7 +57,7 @@ export const SettingsAboutSection = ({
const { getIcon } = useIcons(); const { getIcon } = useIcons();
const Icon = getIcon(iconKey); const Icon = getIcon(iconKey);
const { closeDropdown } = useDropdown({ dropdownScopeId }); const { closeDropdown } = useDropdown(dropdownScopeId);
const handleEdit = () => { const handleEdit = () => {
onEdit(); onEdit();

View File

@ -27,7 +27,7 @@ export const SettingsObjectFieldActiveActionDropdown = ({
}: SettingsObjectFieldActiveActionDropdownProps) => { }: SettingsObjectFieldActiveActionDropdownProps) => {
const dropdownScopeId = `${scopeKey}-settings-field-active-action-dropdown`; const dropdownScopeId = `${scopeKey}-settings-field-active-action-dropdown`;
const { closeDropdown } = useDropdown({ dropdownScopeId }); const { closeDropdown } = useDropdown(dropdownScopeId);
const handleEdit = () => { const handleEdit = () => {
onEdit(); onEdit();

View File

@ -20,7 +20,7 @@ export const SettingsObjectFieldDisabledActionDropdown = ({
}: SettingsObjectFieldDisabledActionDropdownProps) => { }: SettingsObjectFieldDisabledActionDropdownProps) => {
const dropdownScopeId = `${scopeKey}-settings-field-disabled-action-dropdown`; const dropdownScopeId = `${scopeKey}-settings-field-disabled-action-dropdown`;
const { closeDropdown } = useDropdown({ dropdownScopeId }); const { closeDropdown } = useDropdown(dropdownScopeId);
const handleActivate = () => { const handleActivate = () => {
onActivate(); onActivate();

View File

@ -22,7 +22,7 @@ export const SettingsObjectDisabledMenuDropDown = ({
}: SettingsObjectDisabledMenuDropDownProps) => { }: SettingsObjectDisabledMenuDropDownProps) => {
const dropdownScopeId = `${scopeKey}-settings-object-disabled-menu-dropdown`; const dropdownScopeId = `${scopeKey}-settings-object-disabled-menu-dropdown`;
const { closeDropdown } = useDropdown({ dropdownScopeId }); const { closeDropdown } = useDropdown(dropdownScopeId);
const handleActivate = () => { const handleActivate = () => {
onActivate(); onActivate();

View File

@ -27,8 +27,8 @@ export const SignInBackgroundMockPage = () => {
<StyledTableContainer> <StyledTableContainer>
<SignInBackgroundMockContainer /> <SignInBackgroundMockContainer />
</StyledTableContainer> </StyledTableContainer>
<RecordTableActionBar /> <RecordTableActionBar recordTableId="mock" />
<RecordTableContextMenu /> <RecordTableContextMenu recordTableId="mock" />
</PageBody> </PageBody>
</PageContainer> </PageContainer>
); );

View File

@ -95,7 +95,7 @@ export const IconPicker = ({
setHotkeyScopeAndMemorizePreviousScope, setHotkeyScopeAndMemorizePreviousScope,
} = usePreviousHotkeyScope(); } = usePreviousHotkeyScope();
const { closeDropdown } = useDropdown({ dropdownScopeId }); const { closeDropdown } = useDropdown(dropdownScopeId);
const { getIcons, getIcon } = useIcons(); const { getIcons, getIcon } = useIcons();
const icons = getIcons(); const icons = getIcons();

View File

@ -74,7 +74,7 @@ export const Select = <Value extends string | number | null>({
const selectedOption = const selectedOption =
options.find(({ value: key }) => key === value) || options[0]; options.find(({ value: key }) => key === value) || options[0];
const { closeDropdown } = useDropdown({ dropdownScopeId }); const { closeDropdown } = useDropdown(dropdownScopeId);
const selectControl = ( const selectControl = (
<StyledControlContainer disabled={disabled} fullWidth={fullWidth}> <StyledControlContainer disabled={disabled} fullWidth={fullWidth}>

View File

@ -75,9 +75,7 @@ export const CountryPickerDropdownButton = ({
const [selectedCountry, setSelectedCountry] = useState<Country>(); const [selectedCountry, setSelectedCountry] = useState<Country>();
const { isDropdownOpen, closeDropdown } = useDropdown({ const { isDropdownOpen, closeDropdown } = useDropdown('country-picker');
dropdownScopeId: 'country-picker',
});
const handleChange = (countryCode: string) => { const handleChange = (countryCode: string) => {
onChange(countryCode); onChange(countryCode);

View File

@ -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,
};
};

View File

@ -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 { 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 { const {
setHotkeyScopeAndMemorizePreviousScope, setHotkeyScopeAndMemorizePreviousScope,
goBackToPreviousHotkeyScope, goBackToPreviousHotkeyScope,
} = usePreviousHotkeyScope(); } = usePreviousHotkeyScope();
const scopeId = useAvailableScopeIdOrThrow( const [dropdownHotkeyScope, setDropdownHotkeyScope] = useRecoilState(
DropdownScopeInternalContext, injectStateWithDropdownScopeId(dropdownHotkeyScopeScopeInjector),
props?.dropdownScopeId,
); );
const { const [dropdownWidth, setDropdownWidth] = useRecoilState(
dropdownHotkeyScope, injectStateWithDropdownScopeId(dropdownWidthScopeInjector),
setDropdownHotkeyScope, );
isDropdownOpen,
setIsDropdownOpen,
dropdownWidth,
setDropdownWidth,
} = useDropdownStates({
scopeId,
});
const closeDropdownButton = () => { const [isDropdownOpen, setIsDropdownOpen] = useRecoilState(
injectStateWithDropdownScopeId(isDropdownOpenScopeInjector),
);
const closeDropdown = () => {
goBackToPreviousHotkeyScope(); goBackToPreviousHotkeyScope();
setIsDropdownOpen(false); setIsDropdownOpen(false);
}; };
const openDropdownButton = () => { const openDropdown = () => {
setIsDropdownOpen(true); setIsDropdownOpen(true);
if (dropdownHotkeyScope) { if (dropdownHotkeyScope) {
setHotkeyScopeAndMemorizePreviousScope( setHotkeyScopeAndMemorizePreviousScope(
dropdownHotkeyScope.scope, dropdownHotkeyScope.scope,
@ -47,20 +47,20 @@ export const useDropdown = (props?: UseDropdownProps) => {
} }
}; };
const toggleDropdownButton = () => { const toggleDropdown = () => {
if (isDropdownOpen) { if (isDropdownOpen) {
closeDropdownButton(); closeDropdown();
} else { } else {
openDropdownButton(); openDropdown();
} }
}; };
return { return {
scopeId, scopeId,
isDropdownOpen: isDropdownOpen, isDropdownOpen: isDropdownOpen,
closeDropdown: closeDropdownButton, closeDropdown,
toggleDropdown: toggleDropdownButton, toggleDropdown,
openDropdown: openDropdownButton, openDropdown,
dropdownHotkeyScope, dropdownHotkeyScope,
setDropdownHotkeyScope, setDropdownHotkeyScope,
dropdownWidth, dropdownWidth,

View File

@ -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,
};
};

View File

@ -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,
};
};

Some files were not shown because too many files have changed in this diff Show More