feat: persist table columns on change (#1697)
* feat: persist table columns on change Closes #1580 * fix: fix drag-and-select on Table Options dropdown toggle
This commit is contained in:
@ -5,6 +5,7 @@ import { useCompanyTableContextMenuEntries } from '@/companies/hooks/useCompanyT
|
||||
import { useSpreadsheetCompanyImport } from '@/companies/hooks/useSpreadsheetCompanyImport';
|
||||
import { EntityTable } from '@/ui/table/components/EntityTable';
|
||||
import { EntityTableEffect } from '@/ui/table/components/EntityTableEffect';
|
||||
import { TableContext } from '@/ui/table/contexts/TableContext';
|
||||
import { useUpsertEntityTableItem } from '@/ui/table/hooks/useUpsertEntityTableItem';
|
||||
import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||
@ -35,11 +36,16 @@ export const CompanyTable = () => {
|
||||
const upsertEntityTableItem = useUpsertEntityTableItem();
|
||||
|
||||
const [getWorkspaceMember] = useGetWorkspaceMembersLazyQuery();
|
||||
const { createView, deleteView, submitCurrentView, updateView } =
|
||||
useTableViews({
|
||||
objectId: 'company',
|
||||
columnDefinitions: companiesAvailableColumnDefinitions,
|
||||
});
|
||||
const {
|
||||
createView,
|
||||
deleteView,
|
||||
persistColumns,
|
||||
submitCurrentView,
|
||||
updateView,
|
||||
} = useTableViews({
|
||||
objectId: 'company',
|
||||
columnDefinitions: companiesAvailableColumnDefinitions,
|
||||
});
|
||||
|
||||
const { openCompanySpreadsheetImport } = useSpreadsheetCompanyImport();
|
||||
|
||||
@ -76,7 +82,7 @@ export const CompanyTable = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableContext.Provider value={{ onColumnsChange: persistColumns }}>
|
||||
<EntityTableEffect
|
||||
getRequestResultKey="companies"
|
||||
useGetRequest={useGetCompaniesQuery}
|
||||
@ -109,6 +115,6 @@ export const CompanyTable = () => {
|
||||
}) => updateCompany(variables)}
|
||||
/>
|
||||
</ViewBarContext.Provider>
|
||||
</>
|
||||
</TableContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
@ -5,6 +5,7 @@ import { usePersonTableActionBarEntries } from '@/people/hooks/usePersonTableAct
|
||||
import { useSpreadsheetPersonImport } from '@/people/hooks/useSpreadsheetPersonImport';
|
||||
import { EntityTable } from '@/ui/table/components/EntityTable';
|
||||
import { EntityTableEffect } from '@/ui/table/components/EntityTableEffect';
|
||||
import { TableContext } from '@/ui/table/contexts/TableContext';
|
||||
import { useUpsertEntityTableItem } from '@/ui/table/hooks/useUpsertEntityTableItem';
|
||||
import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||
@ -34,11 +35,16 @@ export const PeopleTable = () => {
|
||||
const upsertEntityTableItem = useUpsertEntityTableItem();
|
||||
const { openPersonSpreadsheetImport } = useSpreadsheetPersonImport();
|
||||
|
||||
const { createView, deleteView, submitCurrentView, updateView } =
|
||||
useTableViews({
|
||||
objectId: 'person',
|
||||
columnDefinitions: peopleAvailableColumnDefinitions,
|
||||
});
|
||||
const {
|
||||
createView,
|
||||
deleteView,
|
||||
persistColumns,
|
||||
submitCurrentView,
|
||||
updateView,
|
||||
} = useTableViews({
|
||||
objectId: 'person',
|
||||
columnDefinitions: peopleAvailableColumnDefinitions,
|
||||
});
|
||||
|
||||
const { setContextMenuEntries } = usePersonTableContextMenuEntries();
|
||||
const { setActionBarEntries } = usePersonTableActionBarEntries();
|
||||
@ -48,7 +54,7 @@ export const PeopleTable = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableContext.Provider value={{ onColumnsChange: persistColumns }}>
|
||||
<EntityTableEffect
|
||||
getRequestResultKey="people"
|
||||
useGetRequest={useGetPeopleQuery}
|
||||
@ -91,6 +97,6 @@ export const PeopleTable = () => {
|
||||
}
|
||||
/>
|
||||
</ViewBarContext.Provider>
|
||||
</>
|
||||
</TableContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
@ -10,7 +10,7 @@ import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useLis
|
||||
import { useDropdownButton } from '../hooks/useDropdownButton';
|
||||
import { useInternalHotkeyScopeManagement } from '../hooks/useInternalHotkeyScopeManagement';
|
||||
|
||||
import { DropdownCloseEffect } from './DropdownCloseEffect';
|
||||
import { DropdownToggleEffect } from './DropdownToggleEffect';
|
||||
|
||||
type OwnProps = {
|
||||
buttonComponents?: JSX.Element | JSX.Element[];
|
||||
@ -24,6 +24,7 @@ type OwnProps = {
|
||||
dropdownPlacement?: Placement;
|
||||
onClickOutside?: () => void;
|
||||
onClose?: () => void;
|
||||
onOpen?: () => void;
|
||||
};
|
||||
|
||||
export const DropdownButton = ({
|
||||
@ -35,6 +36,7 @@ export const DropdownButton = ({
|
||||
dropdownPlacement = 'bottom-end',
|
||||
onClickOutside,
|
||||
onClose,
|
||||
onOpen,
|
||||
}: OwnProps) => {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
@ -93,9 +95,10 @@ export const DropdownButton = ({
|
||||
{dropdownComponents}
|
||||
</div>
|
||||
)}
|
||||
<DropdownCloseEffect
|
||||
<DropdownToggleEffect
|
||||
dropdownId={dropdownId}
|
||||
onDropdownClose={() => onClose?.()}
|
||||
onDropdownClose={onClose}
|
||||
onDropdownOpen={onOpen}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -2,20 +2,24 @@ import { useEffect } from 'react';
|
||||
|
||||
import { useDropdownButton } from '../hooks/useDropdownButton';
|
||||
|
||||
export const DropdownCloseEffect = ({
|
||||
export const DropdownToggleEffect = ({
|
||||
dropdownId,
|
||||
onDropdownClose,
|
||||
onDropdownOpen,
|
||||
}: {
|
||||
dropdownId: string;
|
||||
onDropdownClose: () => void;
|
||||
onDropdownClose?: () => void;
|
||||
onDropdownOpen?: () => void;
|
||||
}) => {
|
||||
const { isDropdownButtonOpen } = useDropdownButton({ dropdownId });
|
||||
|
||||
useEffect(() => {
|
||||
if (!isDropdownButtonOpen) {
|
||||
onDropdownClose();
|
||||
if (isDropdownButtonOpen) {
|
||||
onDropdownOpen?.();
|
||||
} else {
|
||||
onDropdownClose?.();
|
||||
}
|
||||
}, [isDropdownButtonOpen, onDropdownClose]);
|
||||
}, [isDropdownButtonOpen, onDropdownClose, onDropdownOpen]);
|
||||
|
||||
return null;
|
||||
};
|
||||
@ -1,6 +1,6 @@
|
||||
import { useRef } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||
@ -90,9 +90,7 @@ type OwnProps = {
|
||||
|
||||
export const EntityTable = ({ updateEntityMutation }: OwnProps) => {
|
||||
const tableBodyRef = useRef<HTMLDivElement>(null);
|
||||
const [isDraggingAndSelecting, setIsDraggingAndSelecting] = useRecoilState(
|
||||
isDraggingAndSelectingState,
|
||||
);
|
||||
const isDraggingAndSelecting = useRecoilValue(isDraggingAndSelectingState);
|
||||
|
||||
const setRowSelectedState = useSetRowSelectedState();
|
||||
const resetTableRowSelection = useResetTableRowSelection();
|
||||
@ -105,7 +103,6 @@ export const EntityTable = ({ updateEntityMutation }: OwnProps) => {
|
||||
refs: [tableBodyRef],
|
||||
callback: () => {
|
||||
leaveTableFocus();
|
||||
setIsDraggingAndSelecting(true);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -7,9 +7,9 @@ import { DropdownRecoilScopeContext } from '@/ui/dropdown/states/recoil-scope-co
|
||||
import { IconPlus } from '@/ui/icon';
|
||||
import { useTrackPointer } from '@/ui/utilities/pointer-event/hooks/useTrackPointer';
|
||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||
|
||||
import { useTableColumns } from '../hooks/useTableColumns';
|
||||
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { resizeFieldOffsetState } from '../states/resizeFieldOffsetState';
|
||||
import { hiddenTableColumnsScopedSelector } from '../states/selectors/hiddenTableColumnsScopedSelector';
|
||||
@ -76,7 +76,7 @@ export const EntityTableHeader = () => {
|
||||
const [resizeFieldOffset, setResizeFieldOffset] = useRecoilState(
|
||||
resizeFieldOffsetState,
|
||||
);
|
||||
const [tableColumns, setTableColumns] = useRecoilScopedState(
|
||||
const tableColumns = useRecoilScopedValue(
|
||||
tableColumnsScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
@ -99,6 +99,8 @@ export const EntityTableHeader = () => {
|
||||
const [resizedFieldKey, setResizedFieldKey] = useState<string | null>(null);
|
||||
const [isColumnMenuOpen, setIsColumnMenuOpen] = useState(false);
|
||||
|
||||
const { handleColumnsChange } = useTableColumns();
|
||||
|
||||
const handleResizeHandlerStart = useCallback((positionX: number) => {
|
||||
setInitialPointerPositionX(positionX);
|
||||
}, []);
|
||||
@ -113,7 +115,7 @@ export const EntityTableHeader = () => {
|
||||
|
||||
const handleResizeHandlerEnd = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
() => {
|
||||
async () => {
|
||||
if (!resizedFieldKey) return;
|
||||
|
||||
const nextWidth = Math.round(
|
||||
@ -131,14 +133,14 @@ export const EntityTableHeader = () => {
|
||||
: column,
|
||||
);
|
||||
|
||||
setTableColumns(nextColumns);
|
||||
await handleColumnsChange(nextColumns);
|
||||
}
|
||||
|
||||
set(resizeFieldOffsetState, 0);
|
||||
setInitialPointerPositionX(null);
|
||||
setResizedFieldKey(null);
|
||||
},
|
||||
[resizedFieldKey, tableColumnsByKey, tableColumns, setTableColumns],
|
||||
[resizedFieldKey, tableColumnsByKey, tableColumns, handleColumnsChange],
|
||||
);
|
||||
|
||||
useTrackPointer({
|
||||
|
||||
11
front/src/modules/ui/table/contexts/TableContext.ts
Normal file
11
front/src/modules/ui/table/contexts/TableContext.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
|
||||
import type { ColumnDefinition } from '../types/ColumnDefinition';
|
||||
|
||||
export const TableContext = createContext<{
|
||||
onColumnsChange?: (
|
||||
columns: ColumnDefinition<ViewFieldMetadata>[],
|
||||
) => void | Promise<void>;
|
||||
}>({});
|
||||
@ -1,15 +1,28 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useCallback, useContext } from 'react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
|
||||
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
|
||||
|
||||
import { TableContext } from '../contexts/TableContext';
|
||||
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { savedTableColumnsFamilyState } from '../states/savedTableColumnsFamilyState';
|
||||
import { tableColumnsByKeyScopedSelector } from '../states/selectors/tableColumnsByKeyScopedSelector';
|
||||
import { tableColumnsScopedState } from '../states/tableColumnsScopedState';
|
||||
import type { ColumnDefinition } from '../types/ColumnDefinition';
|
||||
|
||||
export const useTableColumns = () => {
|
||||
const { onColumnsChange } = useContext(TableContext);
|
||||
|
||||
const currentViewId = useRecoilScopedValue(
|
||||
currentViewIdScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const setSavedTableColumns = useSetRecoilState(
|
||||
savedTableColumnsFamilyState(currentViewId),
|
||||
);
|
||||
const [tableColumns, setTableColumns] = useRecoilScopedState(
|
||||
tableColumnsScopedState,
|
||||
TableRecoilScopeContext,
|
||||
@ -19,21 +32,30 @@ export const useTableColumns = () => {
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
|
||||
const handleColumnReorder = useCallback(
|
||||
(columns: ColumnDefinition<ViewFieldMetadata>[]) => {
|
||||
const updatedColumnOrder = columns
|
||||
.map((column, index) => {
|
||||
return { ...column, index };
|
||||
})
|
||||
.sort((columnA, columnB) => columnA.index - columnB.index);
|
||||
const handleColumnsChange = useCallback(
|
||||
async (columns: ColumnDefinition<ViewFieldMetadata>[]) => {
|
||||
await onColumnsChange?.(columns);
|
||||
|
||||
setTableColumns(updatedColumnOrder);
|
||||
setSavedTableColumns(columns);
|
||||
setTableColumns(columns);
|
||||
},
|
||||
[setTableColumns],
|
||||
[onColumnsChange, setSavedTableColumns, setTableColumns],
|
||||
);
|
||||
|
||||
const handleColumnReorder = useCallback(
|
||||
async (columns: ColumnDefinition<ViewFieldMetadata>[]) => {
|
||||
const updatedColumns = columns.map((column, index) => ({
|
||||
...column,
|
||||
index,
|
||||
}));
|
||||
|
||||
await handleColumnsChange(updatedColumns);
|
||||
},
|
||||
[handleColumnsChange],
|
||||
);
|
||||
|
||||
const handleColumnVisibilityChange = useCallback(
|
||||
(column: ColumnDefinition<ViewFieldMetadata>) => {
|
||||
async (column: ColumnDefinition<ViewFieldMetadata>) => {
|
||||
const nextColumns = tableColumnsByKey[column.key]
|
||||
? tableColumns.map((previousColumn) =>
|
||||
previousColumn.key === column.key
|
||||
@ -44,13 +66,13 @@ export const useTableColumns = () => {
|
||||
(columnA, columnB) => columnA.index - columnB.index,
|
||||
);
|
||||
|
||||
setTableColumns(nextColumns);
|
||||
await handleColumnsChange(nextColumns);
|
||||
},
|
||||
[tableColumnsByKey, tableColumns, setTableColumns],
|
||||
[tableColumnsByKey, tableColumns, handleColumnsChange],
|
||||
);
|
||||
|
||||
const handleColumnMove = useCallback(
|
||||
(direction: string, column: ColumnDefinition<ViewFieldMetadata>) => {
|
||||
async (direction: string, column: ColumnDefinition<ViewFieldMetadata>) => {
|
||||
const currentColumnArrayIndex = tableColumns.findIndex(
|
||||
(tableColumn) => tableColumn.key === column.key,
|
||||
);
|
||||
@ -73,10 +95,10 @@ export const useTableColumns = () => {
|
||||
index: targetColumn.index,
|
||||
};
|
||||
|
||||
setTableColumns(newTableColumns);
|
||||
await handleColumnsChange(newTableColumns);
|
||||
}
|
||||
},
|
||||
[tableColumns, setTableColumns],
|
||||
[tableColumns, handleColumnsChange],
|
||||
);
|
||||
|
||||
const handleColumnLeftMove = useCallback(
|
||||
@ -98,5 +120,6 @@ export const useTableColumns = () => {
|
||||
handleColumnLeftMove,
|
||||
handleColumnRightMove,
|
||||
handleColumnReorder,
|
||||
handleColumnsChange,
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import { useResetRecoilState } from 'recoil';
|
||||
import { useRecoilState, useResetRecoilState } from 'recoil';
|
||||
|
||||
import { DropdownButton } from '@/ui/dropdown/components/DropdownButton';
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
import { viewEditModeState } from '@/ui/view-bar/states/viewEditModeState';
|
||||
|
||||
import { TableOptionsDropdownId } from '../../constants/TableOptionsDropdownId';
|
||||
import { isDraggingAndSelectingState } from '../../states/isDraggingAndSelectingState';
|
||||
|
||||
import { TableOptionsDropdownButton } from './TableOptionsDropdownButton';
|
||||
import { TableOptionsDropdownContent } from './TableOptionsDropdownContent';
|
||||
@ -18,6 +19,14 @@ export const TableOptionsDropdown = ({
|
||||
}: TableOptionsDropdownProps) => {
|
||||
const resetViewEditMode = useResetRecoilState(viewEditModeState);
|
||||
|
||||
const [, setIsDraggingAndSelecting] = useRecoilState(
|
||||
isDraggingAndSelectingState,
|
||||
);
|
||||
|
||||
const handleClose = () => setIsDraggingAndSelecting(true);
|
||||
|
||||
const handleOpen = () => setIsDraggingAndSelecting(false);
|
||||
|
||||
return (
|
||||
<DropdownButton
|
||||
buttonComponents={<TableOptionsDropdownButton />}
|
||||
@ -25,6 +34,8 @@ export const TableOptionsDropdown = ({
|
||||
dropdownId={TableOptionsDropdownId}
|
||||
dropdownComponents={<TableOptionsDropdownContent />}
|
||||
onClickOutside={resetViewEditMode}
|
||||
onClose={handleClose}
|
||||
onOpen={handleOpen}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,27 +1,16 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { StyledHeaderDropdownButton } from '@/ui/dropdown/components/StyledHeaderDropdownButton';
|
||||
import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
|
||||
import { TableOptionsDropdownId } from '@/ui/table/constants/TableOptionsDropdownId';
|
||||
import { isDraggingAndSelectingState } from '@/ui/table/states/isDraggingAndSelectingState';
|
||||
|
||||
export const TableOptionsDropdownButton = () => {
|
||||
const [, setIsDraggingAndSelecting] = useRecoilState(
|
||||
isDraggingAndSelectingState,
|
||||
);
|
||||
const { isDropdownButtonOpen, toggleDropdownButton } = useDropdownButton({
|
||||
dropdownId: TableOptionsDropdownId,
|
||||
});
|
||||
|
||||
const toggleDropdown = () => {
|
||||
setIsDraggingAndSelecting(false);
|
||||
toggleDropdownButton();
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledHeaderDropdownButton
|
||||
isUnfolded={isDropdownButtonOpen}
|
||||
onClick={toggleDropdown}
|
||||
onClick={toggleDropdownButton}
|
||||
>
|
||||
Options
|
||||
</StyledHeaderDropdownButton>
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
import { selectorFamily } from 'recoil';
|
||||
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
import { savedTableColumnsFamilyState } from '../savedTableColumnsFamilyState';
|
||||
import { tableColumnsScopedState } from '../tableColumnsScopedState';
|
||||
|
||||
export const canPersistTableColumnsScopedFamilySelector = selectorFamily({
|
||||
key: 'canPersistTableColumnsScopedFamilySelector',
|
||||
get:
|
||||
({
|
||||
recoilScopeId,
|
||||
viewId,
|
||||
}: {
|
||||
recoilScopeId: string;
|
||||
viewId: string | undefined;
|
||||
}) =>
|
||||
({ get }) =>
|
||||
!isDeeplyEqual(
|
||||
get(savedTableColumnsFamilyState(viewId)),
|
||||
get(tableColumnsScopedState(recoilScopeId)),
|
||||
),
|
||||
});
|
||||
@ -1,21 +1,16 @@
|
||||
import { useContext } from 'react';
|
||||
import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { DropdownRecoilScopeContext } from '@/ui/dropdown/states/recoil-scope-contexts/DropdownRecoilScopeContext';
|
||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
|
||||
import { ViewBar } from '@/ui/view-bar/components/ViewBar';
|
||||
import { ViewBarContext } from '@/ui/view-bar/contexts/ViewBarContext';
|
||||
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
|
||||
|
||||
import { TableOptionsDropdownId } from '../../constants/TableOptionsDropdownId';
|
||||
import { TableOptionsDropdown } from '../../options/components/TableOptionsDropdown';
|
||||
import { isDraggingAndSelectingState } from '../../states/isDraggingAndSelectingState';
|
||||
import { TableRecoilScopeContext } from '../../states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { savedTableColumnsFamilyState } from '../../states/savedTableColumnsFamilyState';
|
||||
import { canPersistTableColumnsScopedFamilySelector } from '../../states/selectors/canPersistTableColumnsScopedFamilySelector';
|
||||
import { tableColumnsScopedState } from '../../states/tableColumnsScopedState';
|
||||
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
|
||||
|
||||
@ -24,29 +19,6 @@ export const TableHeader = () => {
|
||||
useContext(ViewBarContext);
|
||||
const tableRecoilScopeId = useRecoilScopeId(TableRecoilScopeContext);
|
||||
|
||||
const currentViewId = useRecoilScopedValue(
|
||||
currentViewIdScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const canPersistTableColumns = useRecoilValue(
|
||||
canPersistTableColumnsScopedFamilySelector({
|
||||
recoilScopeId: tableRecoilScopeId,
|
||||
viewId: currentViewId,
|
||||
}),
|
||||
);
|
||||
const [tableColumns, setTableColumns] = useRecoilScopedState(
|
||||
tableColumnsScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const [savedTableColumns, setSavedTableColumns] = useRecoilState(
|
||||
savedTableColumnsFamilyState(currentViewId),
|
||||
);
|
||||
const [, setIsDraggingAndSelecting] = useRecoilState(
|
||||
isDraggingAndSelectingState,
|
||||
);
|
||||
|
||||
const handleViewBarReset = () => setTableColumns(savedTableColumns);
|
||||
|
||||
const handleViewSelect = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
async (viewId: string) => {
|
||||
@ -58,23 +30,12 @@ export const TableHeader = () => {
|
||||
[tableRecoilScopeId],
|
||||
);
|
||||
|
||||
const handleCurrentViewSubmit = async () => {
|
||||
if (canPersistTableColumns) {
|
||||
setSavedTableColumns(tableColumns);
|
||||
setIsDraggingAndSelecting(true);
|
||||
}
|
||||
|
||||
await onCurrentViewSubmit?.();
|
||||
};
|
||||
|
||||
return (
|
||||
<RecoilScope CustomRecoilScopeContext={DropdownRecoilScopeContext}>
|
||||
<ViewBarContext.Provider
|
||||
value={{
|
||||
...viewBarContextProps,
|
||||
canPersistViewFields: canPersistTableColumns,
|
||||
onCurrentViewSubmit: handleCurrentViewSubmit,
|
||||
onViewBarReset: handleViewBarReset,
|
||||
onCurrentViewSubmit,
|
||||
onViewSelect: handleViewSelect,
|
||||
}}
|
||||
>
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import { type ReactNode, useContext } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { IconArrowDown, IconArrowUp } from '@/ui/icon/index';
|
||||
import { isDraggingAndSelectingState } from '@/ui/table/states/isDraggingAndSelectingState';
|
||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
|
||||
@ -116,10 +115,6 @@ export const ViewBarDetails = ({
|
||||
ViewBarRecoilScopeContext,
|
||||
);
|
||||
|
||||
const [, setIsDraggingAndSelecting] = useRecoilState(
|
||||
isDraggingAndSelectingState,
|
||||
);
|
||||
|
||||
const savedFilters = useRecoilValue(
|
||||
savedFiltersFamilySelector(currentViewId),
|
||||
);
|
||||
@ -172,7 +167,6 @@ export const ViewBarDetails = ({
|
||||
|
||||
const handleCancelClick = () => {
|
||||
onViewBarReset?.();
|
||||
setIsDraggingAndSelecting(true);
|
||||
setFilters(savedFilters);
|
||||
setSorts(savedSorts);
|
||||
};
|
||||
@ -239,7 +233,7 @@ export const ViewBarDetails = ({
|
||||
data-testid="cancel-button"
|
||||
onClick={handleCancelClick}
|
||||
>
|
||||
Cancel
|
||||
Reset
|
||||
</StyledCancelButton>
|
||||
)}
|
||||
{rightComponent}
|
||||
|
||||
@ -152,32 +152,34 @@ export const useTableViewFields = ({
|
||||
},
|
||||
});
|
||||
|
||||
const persistColumns = useCallback(async () => {
|
||||
if (!currentViewId) return;
|
||||
const persistColumns = useCallback(
|
||||
async (nextColumns: ColumnDefinition<ViewFieldMetadata>[]) => {
|
||||
if (!currentViewId) return;
|
||||
|
||||
const viewFieldsToCreate = tableColumns.filter(
|
||||
(column) => !savedTableColumnsByKey[column.key],
|
||||
);
|
||||
await createViewFields(viewFieldsToCreate);
|
||||
const viewFieldsToCreate = nextColumns.filter(
|
||||
(column) => !savedTableColumnsByKey[column.key],
|
||||
);
|
||||
await createViewFields(viewFieldsToCreate);
|
||||
|
||||
const viewFieldsToUpdate = tableColumns.filter(
|
||||
(column) =>
|
||||
savedTableColumnsByKey[column.key] &&
|
||||
(savedTableColumnsByKey[column.key].size !== column.size ||
|
||||
savedTableColumnsByKey[column.key].index !== column.index ||
|
||||
savedTableColumnsByKey[column.key].isVisible !== column.isVisible),
|
||||
);
|
||||
await updateViewFields(viewFieldsToUpdate);
|
||||
const viewFieldsToUpdate = nextColumns.filter(
|
||||
(column) =>
|
||||
savedTableColumnsByKey[column.key] &&
|
||||
(savedTableColumnsByKey[column.key].size !== column.size ||
|
||||
savedTableColumnsByKey[column.key].index !== column.index ||
|
||||
savedTableColumnsByKey[column.key].isVisible !== column.isVisible),
|
||||
);
|
||||
await updateViewFields(viewFieldsToUpdate);
|
||||
|
||||
return refetch();
|
||||
}, [
|
||||
createViewFields,
|
||||
currentViewId,
|
||||
refetch,
|
||||
savedTableColumnsByKey,
|
||||
tableColumns,
|
||||
updateViewFields,
|
||||
]);
|
||||
await refetch();
|
||||
},
|
||||
[
|
||||
createViewFields,
|
||||
currentViewId,
|
||||
refetch,
|
||||
savedTableColumnsByKey,
|
||||
updateViewFields,
|
||||
],
|
||||
);
|
||||
|
||||
return { createViewFields, persistColumns };
|
||||
};
|
||||
|
||||
@ -58,10 +58,15 @@ export const useTableViews = ({
|
||||
});
|
||||
|
||||
const submitCurrentView = async () => {
|
||||
await persistColumns();
|
||||
await persistFilters();
|
||||
await persistSorts();
|
||||
};
|
||||
|
||||
return { createView, deleteView, submitCurrentView, updateView };
|
||||
return {
|
||||
createView,
|
||||
deleteView,
|
||||
persistColumns,
|
||||
submitCurrentView,
|
||||
updateView,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user