feat: reset table column resizing on ViewBar Cancel button click (#1520)
* feat: reset table column resizing on ViewBar Cancel button click Closes #1500 * Fix according to PR --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -1,11 +1,12 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useRecoilCallback, useRecoilValue, useSetRecoilState } from 'recoil';
|
import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { DropdownRecoilScopeContext } from '@/ui/dropdown/states/recoil-scope-contexts/DropdownRecoilScopeContext';
|
import { DropdownRecoilScopeContext } from '@/ui/dropdown/states/recoil-scope-contexts/DropdownRecoilScopeContext';
|
||||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||||
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
|
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
|
||||||
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||||
import { ViewBar, type ViewBarProps } from '@/ui/view-bar/components/ViewBar';
|
import { ViewBar, ViewBarProps } from '@/ui/view-bar/components/ViewBar';
|
||||||
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
|
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
|
||||||
|
|
||||||
import { TableOptionsDropdown } from '../../options/components/TableOptionsDropdown';
|
import { TableOptionsDropdown } from '../../options/components/TableOptionsDropdown';
|
||||||
@ -38,14 +39,18 @@ export function TableHeader<SortField>({
|
|||||||
const canPersistTableColumns = useRecoilValue(
|
const canPersistTableColumns = useRecoilValue(
|
||||||
canPersistTableColumnsScopedFamilySelector([tableScopeId, currentViewId]),
|
canPersistTableColumnsScopedFamilySelector([tableScopeId, currentViewId]),
|
||||||
);
|
);
|
||||||
const tableColumns = useRecoilScopedValue(
|
const [tableColumns, setTableColumns] = useRecoilScopedState(
|
||||||
tableColumnsScopedState,
|
tableColumnsScopedState,
|
||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
const setSavedTableColumns = useSetRecoilState(
|
const [savedTableColumns, setSavedTableColumns] = useRecoilState(
|
||||||
savedTableColumnsFamilyState(currentViewId),
|
savedTableColumnsFamilyState(currentViewId),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function handleViewBarReset() {
|
||||||
|
setTableColumns(savedTableColumns);
|
||||||
|
}
|
||||||
|
|
||||||
const handleViewSelect = useRecoilCallback(
|
const handleViewSelect = useRecoilCallback(
|
||||||
({ set, snapshot }) =>
|
({ set, snapshot }) =>
|
||||||
async (viewId: string) => {
|
async (viewId: string) => {
|
||||||
@ -57,11 +62,13 @@ export function TableHeader<SortField>({
|
|||||||
[tableScopeId],
|
[tableScopeId],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleViewSubmit = async () => {
|
async function handleViewSubmit() {
|
||||||
if (canPersistTableColumns) setSavedTableColumns(tableColumns);
|
if (canPersistTableColumns) {
|
||||||
|
setSavedTableColumns(tableColumns);
|
||||||
|
}
|
||||||
|
|
||||||
await onViewSubmit?.();
|
await onViewSubmit?.();
|
||||||
};
|
}
|
||||||
|
|
||||||
const OptionsDropdownButton = useCallback(
|
const OptionsDropdownButton = useCallback(
|
||||||
() => (
|
() => (
|
||||||
@ -79,6 +86,7 @@ export function TableHeader<SortField>({
|
|||||||
<ViewBar
|
<ViewBar
|
||||||
{...props}
|
{...props}
|
||||||
canPersistViewFields={canPersistTableColumns}
|
canPersistViewFields={canPersistTableColumns}
|
||||||
|
onReset={handleViewBarReset}
|
||||||
onViewSelect={handleViewSelect}
|
onViewSelect={handleViewSelect}
|
||||||
onViewSubmit={handleViewSubmit}
|
onViewSubmit={handleViewSubmit}
|
||||||
OptionsDropdownButton={OptionsDropdownButton}
|
OptionsDropdownButton={OptionsDropdownButton}
|
||||||
|
|||||||
@ -1,34 +1,27 @@
|
|||||||
import { ComponentProps, type ComponentType, type Context } from 'react';
|
import type { ComponentProps, ComponentType, Context } from 'react';
|
||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
|
|
||||||
import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
|
import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
|
||||||
import { TopBar } from '@/ui/top-bar/TopBar';
|
import { TopBar } from '@/ui/top-bar/TopBar';
|
||||||
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
|
|
||||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
|
||||||
|
|
||||||
import { currentViewIdScopedState } from '../states/currentViewIdScopedState';
|
|
||||||
import { canPersistFiltersScopedFamilySelector } from '../states/selectors/canPersistFiltersScopedFamilySelector';
|
|
||||||
import { canPersistSortsScopedFamilySelector } from '../states/selectors/canPersistSortsScopedFamilySelector';
|
|
||||||
import { FiltersHotkeyScope } from '../types/FiltersHotkeyScope';
|
import { FiltersHotkeyScope } from '../types/FiltersHotkeyScope';
|
||||||
import { ViewsHotkeyScope } from '../types/ViewsHotkeyScope';
|
import { ViewsHotkeyScope } from '../types/ViewsHotkeyScope';
|
||||||
|
|
||||||
import { FilterDropdownButton } from './FilterDropdownButton';
|
import { FilterDropdownButton } from './FilterDropdownButton';
|
||||||
import {
|
import {
|
||||||
SortDropdownButton,
|
SortDropdownButton,
|
||||||
SortDropdownButtonProps,
|
type SortDropdownButtonProps,
|
||||||
} from './SortDropdownButton';
|
} from './SortDropdownButton';
|
||||||
import {
|
import {
|
||||||
UpdateViewButtonGroup,
|
UpdateViewButtonGroup,
|
||||||
UpdateViewButtonGroupProps,
|
type UpdateViewButtonGroupProps,
|
||||||
} from './UpdateViewButtonGroup';
|
} from './UpdateViewButtonGroup';
|
||||||
import ViewBarDetails from './ViewBarDetails';
|
import ViewBarDetails, { type ViewBarDetailsProps } from './ViewBarDetails';
|
||||||
import {
|
import {
|
||||||
ViewsDropdownButton,
|
ViewsDropdownButton,
|
||||||
ViewsDropdownButtonProps,
|
type ViewsDropdownButtonProps,
|
||||||
} from './ViewsDropdownButton';
|
} from './ViewsDropdownButton';
|
||||||
|
|
||||||
export type ViewBarProps<SortField> = ComponentProps<'div'> & {
|
export type ViewBarProps<SortField> = ComponentProps<'div'> & {
|
||||||
canPersistViewFields?: boolean;
|
|
||||||
OptionsDropdownButton: ComponentType;
|
OptionsDropdownButton: ComponentType;
|
||||||
optionsDropdownKey: string;
|
optionsDropdownKey: string;
|
||||||
scopeContext: Context<string | null>;
|
scopeContext: Context<string | null>;
|
||||||
@ -37,12 +30,14 @@ export type ViewBarProps<SortField> = ComponentProps<'div'> & {
|
|||||||
'defaultViewName' | 'onViewsChange' | 'onViewSelect'
|
'defaultViewName' | 'onViewsChange' | 'onViewSelect'
|
||||||
> &
|
> &
|
||||||
Pick<SortDropdownButtonProps<SortField>, 'availableSorts'> &
|
Pick<SortDropdownButtonProps<SortField>, 'availableSorts'> &
|
||||||
|
Pick<ViewBarDetailsProps, 'canPersistViewFields' | 'onReset'> &
|
||||||
Pick<UpdateViewButtonGroupProps, 'onViewSubmit'>;
|
Pick<UpdateViewButtonGroupProps, 'onViewSubmit'>;
|
||||||
|
|
||||||
export const ViewBar = <SortField,>({
|
export const ViewBar = <SortField,>({
|
||||||
availableSorts,
|
availableSorts,
|
||||||
canPersistViewFields,
|
canPersistViewFields,
|
||||||
defaultViewName,
|
defaultViewName,
|
||||||
|
onReset,
|
||||||
onViewsChange,
|
onViewsChange,
|
||||||
onViewSelect,
|
onViewSelect,
|
||||||
onViewSubmit,
|
onViewSubmit,
|
||||||
@ -51,19 +46,6 @@ export const ViewBar = <SortField,>({
|
|||||||
scopeContext,
|
scopeContext,
|
||||||
...props
|
...props
|
||||||
}: ViewBarProps<SortField>) => {
|
}: ViewBarProps<SortField>) => {
|
||||||
const recoilScopeId = useContextScopeId(scopeContext);
|
|
||||||
|
|
||||||
const currentViewId = useRecoilScopedValue(
|
|
||||||
currentViewIdScopedState,
|
|
||||||
scopeContext,
|
|
||||||
);
|
|
||||||
const canPersistFilters = useRecoilValue(
|
|
||||||
canPersistFiltersScopedFamilySelector([recoilScopeId, currentViewId]),
|
|
||||||
);
|
|
||||||
const canPersistSorts = useRecoilValue(
|
|
||||||
canPersistSortsScopedFamilySelector([recoilScopeId, currentViewId]),
|
|
||||||
);
|
|
||||||
|
|
||||||
const { openDropdownButton: openOptionsDropdownButton } = useDropdownButton({
|
const { openDropdownButton: openOptionsDropdownButton } = useDropdownButton({
|
||||||
key: optionsDropdownKey,
|
key: optionsDropdownKey,
|
||||||
});
|
});
|
||||||
@ -100,13 +82,13 @@ export const ViewBar = <SortField,>({
|
|||||||
}
|
}
|
||||||
bottomComponent={
|
bottomComponent={
|
||||||
<ViewBarDetails
|
<ViewBarDetails
|
||||||
canPersistView={
|
canPersistViewFields={canPersistViewFields}
|
||||||
canPersistViewFields || canPersistFilters || canPersistSorts
|
|
||||||
}
|
|
||||||
context={scopeContext}
|
context={scopeContext}
|
||||||
hasFilterButton
|
hasFilterButton
|
||||||
|
onReset={onReset}
|
||||||
rightComponent={
|
rightComponent={
|
||||||
<UpdateViewButtonGroup
|
<UpdateViewButtonGroup
|
||||||
|
canPersistViewFields={canPersistViewFields}
|
||||||
onViewEditModeChange={openOptionsDropdownButton}
|
onViewEditModeChange={openOptionsDropdownButton}
|
||||||
onViewSubmit={onViewSubmit}
|
onViewSubmit={onViewSubmit}
|
||||||
hotkeyScope={ViewsHotkeyScope.CreateDropdown}
|
hotkeyScope={ViewsHotkeyScope.CreateDropdown}
|
||||||
|
|||||||
@ -1,18 +1,24 @@
|
|||||||
import type { Context, ReactNode } from 'react';
|
import type { Context, ReactNode } from 'react';
|
||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IconArrowNarrowDown,
|
IconArrowNarrowDown,
|
||||||
IconArrowNarrowUp,
|
IconArrowNarrowUp,
|
||||||
IconPlus,
|
IconPlus,
|
||||||
} from '@/ui/icon/index';
|
} from '@/ui/icon/index';
|
||||||
|
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
|
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||||
|
|
||||||
import { useRemoveFilter } from '../hooks/useRemoveFilter';
|
import { useRemoveFilter } from '../hooks/useRemoveFilter';
|
||||||
import { availableFiltersScopedState } from '../states/availableFiltersScopedState';
|
import { availableFiltersScopedState } from '../states/availableFiltersScopedState';
|
||||||
|
import { currentViewIdScopedState } from '../states/currentViewIdScopedState';
|
||||||
import { filtersScopedState } from '../states/filtersScopedState';
|
import { filtersScopedState } from '../states/filtersScopedState';
|
||||||
import { isViewBarExpandedScopedState } from '../states/isViewBarExpandedScopedState';
|
import { isViewBarExpandedScopedState } from '../states/isViewBarExpandedScopedState';
|
||||||
|
import { canPersistFiltersScopedFamilySelector } from '../states/selectors/canPersistFiltersScopedFamilySelector';
|
||||||
|
import { canPersistSortsScopedFamilySelector } from '../states/selectors/canPersistSortsScopedFamilySelector';
|
||||||
import { sortsScopedState } from '../states/sortsScopedState';
|
import { sortsScopedState } from '../states/sortsScopedState';
|
||||||
import { FiltersHotkeyScope } from '../types/FiltersHotkeyScope';
|
import { FiltersHotkeyScope } from '../types/FiltersHotkeyScope';
|
||||||
import { SelectedSortType } from '../types/interface';
|
import { SelectedSortType } from '../types/interface';
|
||||||
@ -21,10 +27,11 @@ import { getOperandLabelShort } from '../utils/getOperandLabel';
|
|||||||
import { FilterDropdownButton } from './FilterDropdownButton';
|
import { FilterDropdownButton } from './FilterDropdownButton';
|
||||||
import SortOrFilterChip from './SortOrFilterChip';
|
import SortOrFilterChip from './SortOrFilterChip';
|
||||||
|
|
||||||
type OwnProps = {
|
export type ViewBarDetailsProps = {
|
||||||
canPersistView?: boolean;
|
canPersistViewFields?: boolean;
|
||||||
context: Context<string | null>;
|
context: Context<string | null>;
|
||||||
hasFilterButton?: boolean;
|
hasFilterButton?: boolean;
|
||||||
|
onReset?: () => void;
|
||||||
rightComponent?: ReactNode;
|
rightComponent?: ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -96,13 +103,18 @@ const StyledAddFilterContainer = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
function ViewBarDetails<SortField>({
|
function ViewBarDetails<SortField>({
|
||||||
canPersistView,
|
canPersistViewFields,
|
||||||
context,
|
context,
|
||||||
hasFilterButton = false,
|
hasFilterButton = false,
|
||||||
|
onReset,
|
||||||
rightComponent,
|
rightComponent,
|
||||||
}: OwnProps) {
|
}: ViewBarDetailsProps) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
|
const recoilScopeId = useContextScopeId(context);
|
||||||
|
|
||||||
|
const currentViewId = useRecoilScopedValue(currentViewIdScopedState, context);
|
||||||
|
|
||||||
const [filters, setFilters] = useRecoilScopedState(
|
const [filters, setFilters] = useRecoilScopedState(
|
||||||
filtersScopedState,
|
filtersScopedState,
|
||||||
context,
|
context,
|
||||||
@ -111,11 +123,20 @@ function ViewBarDetails<SortField>({
|
|||||||
availableFiltersScopedState,
|
availableFiltersScopedState,
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
|
const canPersistFilters = useRecoilValue(
|
||||||
|
canPersistFiltersScopedFamilySelector([recoilScopeId, currentViewId]),
|
||||||
|
);
|
||||||
|
|
||||||
const [sorts, setSorts] = useRecoilScopedState<SelectedSortType<SortField>[]>(
|
const [sorts, setSorts] = useRecoilScopedState<SelectedSortType<SortField>[]>(
|
||||||
sortsScopedState,
|
sortsScopedState,
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
|
const canPersistSorts = useRecoilValue(
|
||||||
|
canPersistSortsScopedFamilySelector([recoilScopeId, currentViewId]),
|
||||||
|
);
|
||||||
|
|
||||||
|
const canPersistView =
|
||||||
|
canPersistViewFields || canPersistFilters || canPersistSorts;
|
||||||
|
|
||||||
const [isViewBarExpanded] = useRecoilScopedState(
|
const [isViewBarExpanded] = useRecoilScopedState(
|
||||||
isViewBarExpandedScopedState,
|
isViewBarExpandedScopedState,
|
||||||
@ -136,6 +157,7 @@ function ViewBarDetails<SortField>({
|
|||||||
const removeFilter = useRemoveFilter(context);
|
const removeFilter = useRemoveFilter(context);
|
||||||
|
|
||||||
function handleCancelClick() {
|
function handleCancelClick() {
|
||||||
|
onReset?.();
|
||||||
setFilters([]);
|
setFilters([]);
|
||||||
setSorts([]);
|
setSorts([]);
|
||||||
}
|
}
|
||||||
@ -207,7 +229,7 @@ function ViewBarDetails<SortField>({
|
|||||||
</StyledAddFilterContainer>
|
</StyledAddFilterContainer>
|
||||||
)}
|
)}
|
||||||
</StyledFilterContainer>
|
</StyledFilterContainer>
|
||||||
{filters.length + sorts.length > 0 && (
|
{(filters.length + sorts.length > 0 || canPersistViewFields) && (
|
||||||
<StyledCancelButton
|
<StyledCancelButton
|
||||||
data-testid="cancel-button"
|
data-testid="cancel-button"
|
||||||
onClick={handleCancelClick}
|
onClick={handleCancelClick}
|
||||||
|
|||||||
Reference in New Issue
Block a user