Improve viewbar api (#2233)

* create scopes

* fix import bug

* add useView hook

* wip

* wip

* currentViewId is now retrieved via useView

* working on sorts with useView

* refactor in progress

* refactor in progress

* refactor in progress

* refactor in progress

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* fix code

* fix code

* wip

* push

* Fix issue dependencies

* Fix resize

---------

Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
This commit is contained in:
Charles Bochet
2023-10-27 10:52:26 +02:00
committed by GitHub
parent 6a72c14af3
commit 5ba68e997d
205 changed files with 3092 additions and 3249 deletions

View File

@ -14,7 +14,6 @@ import { useLeaveTableFocus } from '../hooks/useLeaveTableFocus';
import { useMapKeyboardToSoftFocus } from '../hooks/useMapKeyboardToSoftFocus';
import { useResetTableRowSelection } from '../hooks/useResetTableRowSelection';
import { useSetRowSelectedState } from '../hooks/useSetRowSelectedState';
import { TableHeader } from '../table-header/components/TableHeader';
import { TableHotkeyScope } from '../types/TableHotkeyScope';
import { DataTableBody } from './DataTableBody';
@ -123,7 +122,6 @@ export const DataTable = ({ updateEntityMutation }: DataTableProps) => {
<EntityUpdateMutationContext.Provider value={updateEntityMutation}>
<StyledTableWithHeader>
<StyledTableContainer ref={tableBodyRef}>
<TableHeader />
<ScrollWrapper>
<div>
<StyledTable className="entity-table-cell">

View File

@ -1,27 +1,21 @@
import { useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
import defaults from 'lodash/defaults';
import { useRecoilCallback } from 'recoil';
import { useOptimisticEffect } from '@/apollo/optimistic-effect/hooks/useOptimisticEffect';
import { OptimisticEffectDefinition } from '@/apollo/optimistic-effect/types/OptimisticEffectDefinition';
import { currentViewIdScopedState } from '@/ui/data/view-bar/states/currentViewIdScopedState';
import { filtersScopedState } from '@/ui/data/view-bar/states/filtersScopedState';
import { savedFiltersFamilyState } from '@/ui/data/view-bar/states/savedFiltersFamilyState';
import { savedSortsFamilyState } from '@/ui/data/view-bar/states/savedSortsFamilyState';
import { sortsScopedState } from '@/ui/data/view-bar/states/sortsScopedState';
import { FilterDefinition } from '@/ui/data/view-bar/types/FilterDefinition';
import { SortDefinition } from '@/ui/data/view-bar/types/SortDefinition';
import { FilterDefinition } from '@/ui/data/filter/types/FilterDefinition';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
import { useView } from '@/views/hooks/useView';
import { useViewInternalStates } from '@/views/hooks/useViewInternalStates';
import {
SortOrder,
useGetCompaniesQuery,
useGetPeopleQuery,
} from '~/generated/graphql';
import { filtersWhereScopedSelector } from '../../view-bar/states/selectors/filtersWhereScopedSelector';
import { sortsOrderByScopedSelector } from '../../view-bar/states/selectors/sortsOrderByScopedSelector';
import { filtersWhereScopedSelector } from '../../filter/states/selectors/filtersWhereScopedSelector';
import { SortDefinition } from '../../sort/types/SortDefinition';
import { useSetDataTableData } from '../hooks/useSetDataTableData';
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
@ -46,12 +40,10 @@ export const DataTableEffect = ({
}) => {
const setDataTableData = useSetDataTableData();
const { registerOptimisticEffect } = useOptimisticEffect();
const { setCurrentViewId } = useView();
const { currentViewSortsOrderBy } = useViewInternalStates();
let sortsOrderBy = useRecoilScopedValue(
sortsOrderByScopedSelector,
TableRecoilScopeContext,
);
sortsOrderBy = defaults(sortsOrderBy, [
const sortsOrderBy = defaults(currentViewSortsOrderBy, [
{
createdAt: SortOrder.Desc,
},
@ -76,43 +68,19 @@ export const DataTableEffect = ({
});
const [searchParams] = useSearchParams();
const tableRecoilScopeId = useRecoilScopeId(TableRecoilScopeContext);
const handleViewSelect = useRecoilCallback(
({ set, snapshot }) =>
async (viewId: string) => {
const currentView = await snapshot.getPromise(
currentViewIdScopedState(tableRecoilScopeId),
);
if (currentView === viewId) {
return;
}
const savedFilters = await snapshot.getPromise(
savedFiltersFamilyState(viewId),
);
const savedSorts = await snapshot.getPromise(
savedSortsFamilyState(viewId),
);
set(filtersScopedState(tableRecoilScopeId), savedFilters);
set(sortsScopedState(tableRecoilScopeId), savedSorts);
set(currentViewIdScopedState(tableRecoilScopeId), viewId);
},
[tableRecoilScopeId],
);
useEffect(() => {
const viewId = searchParams.get('view');
if (viewId) {
handleViewSelect(viewId);
//setCurrentViewId(viewId);
}
setActionBarEntries?.();
setContextMenuEntries?.();
}, [
handleViewSelect,
searchParams,
setActionBarEntries,
setContextMenuEntries,
setCurrentViewId,
]);
return <></>;

View File

@ -166,33 +166,35 @@ export const DataTableHeader = () => {
>
<SelectAllCheckbox />
</th>
{visibleTableColumns.map((column, index) => (
<StyledColumnHeaderCell
key={column.key}
isResizing={resizedFieldKey === column.key}
columnWidth={Math.max(
tableColumnsByKey[column.key].size +
(resizedFieldKey === column.key ? resizeFieldOffset : 0),
COLUMN_MIN_WIDTH,
)}
>
<StyledColumnHeadContainer>
<ColumnHeadWithDropdown
column={column}
isFirstColumn={index === 1}
isLastColumn={index === visibleTableColumns.length - 1}
primaryColumnKey={primaryColumn.key}
{[...visibleTableColumns]
.sort((columnA, columnB) => columnA.index - columnB.index)
.map((column, index) => (
<StyledColumnHeaderCell
key={column.key}
isResizing={resizedFieldKey === column.key}
columnWidth={Math.max(
tableColumnsByKey[column.key].size +
(resizedFieldKey === column.key ? resizeFieldOffset : 0),
COLUMN_MIN_WIDTH,
)}
>
<StyledColumnHeadContainer>
<ColumnHeadWithDropdown
column={column}
isFirstColumn={index === 1}
isLastColumn={index === visibleTableColumns.length - 1}
primaryColumnKey={primaryColumn.key}
/>
</StyledColumnHeadContainer>
<StyledResizeHandler
className="cursor-col-resize"
role="separator"
onPointerDown={() => {
setResizedFieldKey(column.key);
}}
/>
</StyledColumnHeadContainer>
<StyledResizeHandler
className="cursor-col-resize"
role="separator"
onPointerDown={() => {
setResizedFieldKey(column.key);
}}
/>
</StyledColumnHeaderCell>
))}
</StyledColumnHeaderCell>
))}
<th>
{hiddenTableColumns.length > 0 && (
<StyledColumnHeadContainer>

View File

@ -38,13 +38,15 @@ export const DataTableRow = forwardRef<HTMLTableRowElement, DataTableRowProps>(
<td>
<CheckboxCell />
</td>
{visibleTableColumns.map((column, columnIndex) => {
return (
<ColumnContext.Provider value={column} key={column.key}>
<DataTableCell cellIndex={columnIndex} />
</ColumnContext.Provider>
);
})}
{[...visibleTableColumns]
.sort((columnA, columnB) => columnA.index - columnB.index)
.map((column, columnIndex) => {
return (
<ColumnContext.Provider value={column} key={column.key}>
<DataTableCell cellIndex={columnIndex} />
</ColumnContext.Provider>
);
})}
<td></td>
</StyledRow>
);

View File

@ -0,0 +1,35 @@
export const useMoveViewColumns = () => {
const handleColumnMove = <T extends { index: number }>(
direction: 'left' | 'right',
currentArrayindex: number,
targetArray: T[],
) => {
const targetArrayIndex =
direction === 'left' ? currentArrayindex - 1 : currentArrayindex + 1;
const targetArraySize = targetArray.length - 1;
if (
currentArrayindex >= 0 &&
targetArrayIndex >= 0 &&
currentArrayindex <= targetArraySize &&
targetArrayIndex <= targetArraySize
) {
const currentEntity = targetArray[currentArrayindex];
const targetEntity = targetArray[targetArrayIndex];
const newArray = [...targetArray];
newArray[currentArrayindex] = {
...targetEntity,
index: currentEntity.index,
};
newArray[targetArrayIndex] = {
...currentEntity,
index: targetEntity.index,
};
return newArray;
}
return targetArray;
};
return { handleColumnMove };
};

View File

@ -1,13 +1,12 @@
import { useRecoilCallback } from 'recoil';
import { entityFieldsFamilyState } from '@/ui/data/field/states/entityFieldsFamilyState';
import { availableFiltersScopedState } from '@/ui/data/view-bar/states/availableFiltersScopedState';
import { availableSortsScopedState } from '@/ui/data/view-bar/states/availableSortsScopedState';
import { entityCountInCurrentViewState } from '@/ui/data/view-bar/states/entityCountInCurrentViewState';
import { FilterDefinition } from '@/ui/data/view-bar/types/FilterDefinition';
import { SortDefinition } from '@/ui/data/view-bar/types/SortDefinition';
import { FilterDefinition } from '@/ui/data/filter/types/FilterDefinition';
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
import { useView } from '@/views/hooks/useView';
import { availableSortsScopedState } from '@/views/states/availableSortsScopedState';
import { SortDefinition } from '../../sort/types/SortDefinition';
import { isFetchingDataTableDataState } from '../states/isFetchingDataTableDataState';
import { numberOfTableRowsState } from '../states/numberOfTableRowsState';
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
@ -17,6 +16,7 @@ import { useResetTableRowSelection } from './useResetTableRowSelection';
export const useSetDataTableData = () => {
const resetTableRowSelection = useResetTableRowSelection();
const { setEntityCountInCurrentView } = useView();
const tableContextScopeId = useRecoilScopeId(TableRecoilScopeContext);
@ -51,20 +51,15 @@ export const useSetDataTableData = () => {
set(numberOfTableRowsState, entityIds.length);
set(entityCountInCurrentViewState, entityIds.length);
setEntityCountInCurrentView(entityIds.length);
set(
availableFiltersScopedState(tableContextScopeId),
filterDefinitionArray,
);
set(
availableSortsScopedState(tableContextScopeId),
availableSortsScopedState({ scopeId: tableContextScopeId }),
sortDefinitionArray,
);
set(isFetchingDataTableDataState, false);
},
[resetTableRowSelection, tableContextScopeId],
[resetTableRowSelection, setEntityCountInCurrentView, tableContextScopeId],
);
};

View File

@ -1,12 +1,11 @@
import { useCallback, useContext } from 'react';
import { useSetRecoilState } from 'recoil';
import { useMoveViewColumns } from '@/ui/data/data-table/hooks/useMoveViewColumns';
import { FieldMetadata } from '@/ui/data/field/types/FieldMetadata';
import { currentViewIdScopedState } from '@/ui/data/view-bar/states/currentViewIdScopedState';
import { ViewFieldForVisibility } from '@/ui/data/view-bar/types/ViewFieldForVisibility';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { useMoveViewColumns } from '@/views/hooks/useMoveViewColumns';
import { useView } from '@/views/hooks/useView';
import { ViewFieldForVisibility } from '@/views/types/ViewFieldForVisibility';
import { TableContext } from '../contexts/TableContext';
import { availableTableColumnsScopedState } from '../states/availableTableColumnsScopedState';
@ -23,10 +22,8 @@ export const useTableColumns = () => {
TableRecoilScopeContext,
);
const currentViewId = useRecoilScopedValue(
currentViewIdScopedState,
TableRecoilScopeContext,
);
const { currentViewId } = useView();
const setSavedTableColumns = useSetRecoilState(
savedTableColumnsFamilyState(currentViewId),
);
@ -91,7 +88,10 @@ export const useTableColumns = () => {
);
const handleMoveTableColumn = useCallback(
(direction: 'left' | 'right', column: ColumnDefinition<FieldMetadata>) => {
async (
direction: 'left' | 'right',
column: ColumnDefinition<FieldMetadata>,
) => {
const currentColumnArrayIndex = tableColumns.findIndex(
(tableColumn) => tableColumn.key === column.key,
);
@ -101,9 +101,9 @@ export const useTableColumns = () => {
tableColumns,
);
setTableColumns(columns);
await handleColumnsChange(columns);
},
[tableColumns, setTableColumns, handleColumnMove],
[tableColumns, handleColumnMove, handleColumnsChange],
);
return {

View File

@ -1,9 +1,7 @@
import { useResetRecoilState } from 'recoil';
import { viewEditModeState } from '@/ui/data/view-bar/states/viewEditModeState';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { useView } from '@/views/hooks/useView';
import { TableOptionsDropdownId } from '../../constants/TableOptionsDropdownId';
@ -17,7 +15,7 @@ type TableOptionsDropdownProps = {
export const TableOptionsDropdown = ({
customHotkeyScope,
}: TableOptionsDropdownProps) => {
const resetViewEditMode = useResetRecoilState(viewEditModeState);
const { setViewEditMode } = useView();
return (
<DropdownScope dropdownScopeId={TableOptionsDropdownId}>
@ -26,7 +24,7 @@ export const TableOptionsDropdown = ({
dropdownHotkeyScope={customHotkeyScope}
dropdownOffset={{ y: 8 }}
dropdownComponents={<TableOptionsDropdownContent />}
onClickOutside={resetViewEditMode}
onClickOutside={() => setViewEditMode('none')}
/>
</DropdownScope>
);

View File

@ -1,15 +1,8 @@
import { useCallback, useContext, useRef, useState } from 'react';
import { useCallback, useRef, useState } from 'react';
import { OnDragEndResponder } from '@hello-pangea/dnd';
import { useRecoilCallback, useRecoilValue, useResetRecoilState } from 'recoil';
import { Key } from 'ts-key-enum';
import { ViewFieldsVisibilityDropdownSection } from '@/ui/data/view-bar/components/ViewFieldsVisibilityDropdownSection';
import { ViewBarContext } from '@/ui/data/view-bar/contexts/ViewBarContext';
import { useUpsertView } from '@/ui/data/view-bar/hooks/useUpsertView';
import { currentViewScopedSelector } from '@/ui/data/view-bar/states/selectors/currentViewScopedSelector';
import { viewsByIdScopedSelector } from '@/ui/data/view-bar/states/selectors/viewsByIdScopedSelector';
import { viewEditModeState } from '@/ui/data/view-bar/states/viewEditModeState';
import { IconChevronLeft, IconFileImport, IconTag } from '@/ui/display/icon';
import { IconChevronLeft, IconTag } from '@/ui/display/icon';
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
import { DropdownMenuInput } from '@/ui/layout/dropdown/components/DropdownMenuInput';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
@ -18,22 +11,22 @@ import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection';
import { useView } from '@/views/hooks/useView';
import { useViewInternalStates } from '@/views/hooks/useViewInternalStates';
import { useTableColumns } from '../../hooks/useTableColumns';
import { TableRecoilScopeContext } from '../../states/recoil-scope-contexts/TableRecoilScopeContext';
import { savedTableColumnsFamilyState } from '../../states/savedTableColumnsFamilyState';
import { hiddenTableColumnsScopedSelector } from '../../states/selectors/hiddenTableColumnsScopedSelector';
import { visibleTableColumnsScopedSelector } from '../../states/selectors/visibleTableColumnsScopedSelector';
import { tableColumnsScopedState } from '../../states/tableColumnsScopedState';
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
type TableOptionsMenu = 'fields';
export const TableOptionsDropdownContent = () => {
const scopeId = useRecoilScopeId(TableRecoilScopeContext);
const { setViewEditMode, handleViewNameSubmit } = useView();
const { viewEditMode, currentView } = useViewInternalStates();
const { onImport } = useContext(ViewBarContext);
const { closeDropdown } = useDropdown();
const [currentMenu, setCurrentMenu] = useState<TableOptionsMenu | undefined>(
@ -42,12 +35,6 @@ export const TableOptionsDropdownContent = () => {
const viewEditInputRef = useRef<HTMLInputElement>(null);
const currentView = useRecoilScopedValue(
currentViewScopedSelector,
TableRecoilScopeContext,
);
const viewEditMode = useRecoilValue(viewEditModeState);
const resetViewEditMode = useResetRecoilState(viewEditModeState);
const visibleTableColumns = useRecoilScopedValue(
visibleTableColumnsScopedSelector,
TableRecoilScopeContext,
@ -56,35 +43,13 @@ export const TableOptionsDropdownContent = () => {
hiddenTableColumnsScopedSelector,
TableRecoilScopeContext,
);
const viewsById = useRecoilScopedValue(
viewsByIdScopedSelector,
TableRecoilScopeContext,
);
const { handleColumnVisibilityChange, handleColumnReorder } =
useTableColumns();
const { upsertView } = useUpsertView();
const handleViewNameSubmit = useRecoilCallback(
({ set, snapshot }) =>
async () => {
const tableColumns = await snapshot.getPromise(
tableColumnsScopedState(scopeId),
);
const isCreateMode = viewEditMode.mode === 'create';
const name = viewEditInputRef.current?.value;
const view = await upsertView(name);
if (view && isCreateMode) {
set(savedTableColumnsFamilyState(view.id), tableColumns);
}
},
[scopeId, upsertView, viewEditMode.mode],
);
const handleSelectMenu = (option: TableOptionsMenu) => {
handleViewNameSubmit();
const name = viewEditInputRef.current?.value;
handleViewNameSubmit(name);
setCurrentMenu(option);
};
@ -108,7 +73,6 @@ export const TableOptionsDropdownContent = () => {
useScopedHotkeys(
Key.Escape,
() => {
resetViewEditMode();
closeDropdown();
},
TableOptionsHotkeyScope.Dropdown,
@ -117,9 +81,10 @@ export const TableOptionsDropdownContent = () => {
useScopedHotkeys(
Key.Enter,
() => {
handleViewNameSubmit();
const name = viewEditInputRef.current?.value;
handleViewNameSubmit(name);
resetMenu();
resetViewEditMode();
setViewEditMode('none');
closeDropdown();
},
TableOptionsHotkeyScope.Dropdown,
@ -130,16 +95,21 @@ export const TableOptionsDropdownContent = () => {
{!currentMenu && (
<>
<DropdownMenuInput
autoFocus={viewEditMode.mode === 'create' || !!viewEditMode.viewId}
ref={viewEditInputRef}
autoFocus={viewEditMode !== 'none'}
placeholder={
viewEditMode.mode === 'create' ? 'New view' : 'View name'
viewEditMode === 'create'
? 'New view'
: viewEditMode === 'edit'
? 'View name'
: ''
}
defaultValue={
viewEditMode.mode === 'create'
viewEditMode === 'create'
? ''
: viewEditMode.viewId
? viewsById[viewEditMode.viewId]?.name
: currentView?.name
: viewEditMode === 'edit'
? currentView?.name
: ''
}
/>
<DropdownMenuSeparator />
@ -149,13 +119,13 @@ export const TableOptionsDropdownContent = () => {
LeftIcon={IconTag}
text="Fields"
/>
{onImport && (
{/*onImport && (
<MenuItem
onClick={onImport}
LeftIcon={IconFileImport}
text="Import"
/>
)}
)*/}
</DropdownMenuItemsContainer>
</>
)}

View File

@ -1,44 +0,0 @@
import { Meta, StoryObj } from '@storybook/react';
import { userEvent, within } from '@storybook/testing-library';
import { ViewBarContext } from '@/ui/data/view-bar/contexts/ViewBarContext';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { TableRecoilScopeContext } from '../../../states/recoil-scope-contexts/TableRecoilScopeContext';
import { TableOptionsDropdown } from '../TableOptionsDropdown';
const meta: Meta<typeof TableOptionsDropdown> = {
title: 'UI/Data/DataTable/Options/TableOptionsDropdown',
component: TableOptionsDropdown,
decorators: [
(Story) => (
<RecoilScope CustomRecoilScopeContext={TableRecoilScopeContext}>
<ViewBarContext.Provider
value={{
ViewBarRecoilScopeContext: TableRecoilScopeContext,
}}
>
<Story />
</ViewBarContext.Provider>
</RecoilScope>
),
ComponentDecorator,
],
};
export default meta;
type Story = StoryObj<typeof TableOptionsDropdown>;
export const Default: Story = {
args: {
customHotkeyScope: { scope: 'options' },
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const dropdownButton = canvas.getByText('Options');
await userEvent.click(dropdownButton);
},
};

View File

@ -1,52 +0,0 @@
import { useContext } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useRecoilCallback } from 'recoil';
import { ViewBar } from '@/ui/data/view-bar/components/ViewBar';
import { ViewBarContext } from '@/ui/data/view-bar/contexts/ViewBarContext';
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
import { TableOptionsDropdownId } from '../../constants/TableOptionsDropdownId';
import { TableOptionsDropdown } from '../../options/components/TableOptionsDropdown';
import { TableRecoilScopeContext } from '../../states/recoil-scope-contexts/TableRecoilScopeContext';
import { savedTableColumnsFamilyState } from '../../states/savedTableColumnsFamilyState';
import { tableColumnsScopedState } from '../../states/tableColumnsScopedState';
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
export const TableHeader = () => {
const { onCurrentViewSubmit, ...viewBarContextProps } =
useContext(ViewBarContext);
const tableRecoilScopeId = useRecoilScopeId(TableRecoilScopeContext);
const [_, setSearchParams] = useSearchParams();
const handleViewSelect = useRecoilCallback(
({ set, snapshot }) =>
async (viewId: string) => {
const savedTableColumns = await snapshot.getPromise(
savedTableColumnsFamilyState(viewId),
);
set(tableColumnsScopedState(tableRecoilScopeId), savedTableColumns);
setSearchParams({ view: viewId });
},
[tableRecoilScopeId, setSearchParams],
);
return (
<ViewBarContext.Provider
value={{
...viewBarContextProps,
onCurrentViewSubmit,
onViewSelect: handleViewSelect,
}}
>
<ViewBar
optionsDropdownButton={
<TableOptionsDropdown
customHotkeyScope={{ scope: TableOptionsHotkeyScope.Dropdown }}
/>
}
optionsDropdownScopeId={TableOptionsDropdownId}
/>
</ViewBarContext.Provider>
);
};