twentyhq / twenty

Building a modern alternative to Salesforce, powered by the community.
https://twenty.com
GNU Affero General Public License v3.0
15.7k stars 1.7k forks source link

bug: Loosing table cell focus after clicking filter/sorrt buttons #5984

Open AdityaPimpalkar opened 2 months ago

AdityaPimpalkar commented 2 months ago

Bug Description

On initial render, we have soft focus on table cell, but after clicking on any of the view bar buttons and then click outside, the focus is not reset to table

https://github.com/twentyhq/twenty/assets/13139771/45a35502-df4e-40af-b7c5-98fc2c29f3f6

Expected behavior

After clicking away from filter/sort button, it should reset the focus back on table

greptile-apps[bot] commented 2 months ago

To fix the issue of losing table cell focus after clicking filter/sort buttons, follow these steps:

  1. Update useLeaveTableFocus:

    • Ensure that useLeaveTableFocus properly resets the focus to the table when clicking outside.
      
      import { useRecoilCallback } from 'recoil';
      import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates';
      import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState';
      import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
      import { TableHotkeyScope } from '../../types/TableHotkeyScope';
      import { useCloseCurrentTableCellInEditMode } from './useCloseCurrentTableCellInEditMode';
      import { useDisableSoftFocus } from './useDisableSoftFocus';

    export const useLeaveTableFocus = (recordTableId?: string) => { const disableSoftFocus = useDisableSoftFocus(recordTableId); const closeCurrentCellInEditMode = useCloseCurrentTableCellInEditMode(recordTableId); const { isSoftFocusActiveState } = useRecordTableStates(recordTableId);

    return useRecoilCallback( ({ snapshot }) => () => { const isSoftFocusActive = getSnapshotValue(snapshot, isSoftFocusActiveState); const currentHotkeyScope = snapshot.getLoadable(currentHotkeyScopeState).getValue();

       if (!isSoftFocusActive) {
         return;
       }
    
       if (currentHotkeyScope?.scope === TableHotkeyScope.Table) {
         return;
       }
    
       closeCurrentCellInEditMode();
       disableSoftFocus();
       // Reset focus to table
       document.querySelector('.table-selector')?.focus();
     },

    [closeCurrentCellInEditMode, disableSoftFocus, isSoftFocusActiveState], ); };

  2. Modify RecordTableInternalEffect:

    • Ensure that the click outside listener properly resets the focus to the table.
      
      import { Key } from 'ts-key-enum';
      import { SOFT_FOCUS_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-table/constants/SoftFocusClickOutsideListenerId';
      import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
      import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
      import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
      import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useClickOutsideListener';
      import { useListenClickOutsideByClassName } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';

    type RecordTableInternalEffectProps = { recordTableId: string; tableBodyRef: React.RefObject; };

    export const RecordTableInternalEffect = ({ recordTableId, tableBodyRef }: RecordTableInternalEffectProps) => { const { leaveTableFocus, resetTableRowSelection, useMapKeyboardToSoftFocus } = useRecordTable({ recordTableId });

    useMapKeyboardToSoftFocus();

    const { useListenClickOutside } = useClickOutsideListener(SOFT_FOCUS_CLICK_OUTSIDE_LISTENER_ID);

    useListenClickOutside({ refs: [tableBodyRef], callback: () => { leaveTableFocus(); // Reset focus to table document.querySelector('.table-selector')?.focus(); }, });

    useScopedHotkeys( [Key.Escape], () => { resetTableRowSelection(); }, TableHotkeyScope.Table, );

    useListenClickOutsideByClassName({ classNames: ['entity-table-cell'], excludeClassNames: ['action-bar', 'context-menu'], callback: () => { resetTableRowSelection(); // Reset focus to table document.querySelector('.table-selector')?.focus(); }, });

    return <></>; };

These changes ensure that the focus is reset to the table after clicking away from the filter/sort buttons.

References

/packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTable.ts /packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellSoftFocusMode.tsx /packages/twenty-front/src/modules/object-record/record-table/components/RecordTableInternalEffect.tsx /packages/twenty-front/src/modules/object-record/record-table/hooks/internal/useLeaveTableFocus.ts /packages/twenty-front/src/modules/object-record/record-table/hooks/useRecordTableMoveFocus.ts

Ask Greptile