Files
twenty_crm/packages/twenty-front/src/modules/views/components/UpdateViewButtonGroup.tsx
Lucas Bordeau aba20dae11 Implemented CRUD for view filter group and removed old states (#10590)
This PR implements CRUD for view filter groups with the new logic as
already done for view filters and view sorts.

It also completely removes the old combined view filter group states and
usage.

This PR is quite big but the impact is limited since it only changes
advanced filters module, which is under feature flag at the moment, and
it is already in a broken state so unusable, even if someone activates
the feature flag.
2025-03-04 13:16:02 +01:00

149 lines
5.1 KiB
TypeScript

import styled from '@emotion/styled';
import {
Button,
ButtonGroup,
IconChevronDown,
IconPlus,
MenuItem,
} from 'twenty-ui';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
import { UPDATE_VIEW_BUTTON_DROPDOWN_ID } from '@/views/constants/UpdateViewButtonDropdownId';
import { useViewFromQueryParams } from '@/views/hooks/internal/useViewFromQueryParams';
import { useAreViewFilterGroupsDifferentFromRecordFilterGroups } from '@/views/hooks/useAreViewFilterGroupsDifferentFromRecordFilterGroups';
import { useAreViewFiltersDifferentFromRecordFilters } from '@/views/hooks/useAreViewFiltersDifferentFromRecordFilters';
import { useAreViewSortsDifferentFromRecordSorts } from '@/views/hooks/useAreViewSortsDifferentFromRecordSorts';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { useSaveCurrentViewFiltersAndSorts } from '@/views/hooks/useSaveCurrentViewFiltersAndSorts';
import { VIEW_PICKER_DROPDOWN_ID } from '@/views/view-picker/constants/ViewPickerDropdownId';
import { useViewPickerMode } from '@/views/view-picker/hooks/useViewPickerMode';
import { viewPickerReferenceViewIdComponentState } from '@/views/view-picker/states/viewPickerReferenceViewIdComponentState';
import { t } from '@lingui/core/macro';
const StyledContainer = styled.div`
border-radius: ${({ theme }) => theme.border.radius.md};
display: inline-flex;
margin-right: ${({ theme }) => theme.spacing(2)};
position: relative;
`;
const StyledButton = styled(Button)`
padding: ${({ theme }) => theme.spacing(1)};
`;
export type UpdateViewButtonGroupProps = {
hotkeyScope: HotkeyScope;
};
export const UpdateViewButtonGroup = ({
hotkeyScope,
}: UpdateViewButtonGroupProps) => {
const { saveCurrentViewFilterAndSorts } = useSaveCurrentViewFiltersAndSorts();
const { setViewPickerMode } = useViewPickerMode();
const currentViewId = useRecoilComponentValueV2(
contextStoreCurrentViewIdComponentState,
);
const { closeDropdown: closeUpdateViewButtonDropdown } = useDropdown(
UPDATE_VIEW_BUTTON_DROPDOWN_ID,
);
const { openDropdown: openViewPickerDropdown } = useDropdown(
VIEW_PICKER_DROPDOWN_ID,
);
const { currentView } = useGetCurrentViewOnly();
const setViewPickerReferenceViewId = useSetRecoilComponentStateV2(
viewPickerReferenceViewIdComponentState,
);
const openViewPickerInCreateMode = () => {
if (!currentViewId) {
return;
}
openViewPickerDropdown();
setViewPickerReferenceViewId(currentViewId);
setViewPickerMode('create-from-current');
closeUpdateViewButtonDropdown();
};
const handleCreateViewClick = () => {
openViewPickerInCreateMode();
};
const handleSaveAsNewViewClick = () => {
openViewPickerInCreateMode();
};
const handleUpdateViewClick = async () => {
await saveCurrentViewFilterAndSorts();
};
const { hasFiltersQueryParams } = useViewFromQueryParams();
const { viewFilterGroupsAreDifferentFromRecordFilterGroups } =
useAreViewFilterGroupsDifferentFromRecordFilterGroups();
const { viewFiltersAreDifferentFromRecordFilters } =
useAreViewFiltersDifferentFromRecordFilters();
const { viewSortsAreDifferentFromRecordSorts } =
useAreViewSortsDifferentFromRecordSorts();
const canShowButton =
(viewFiltersAreDifferentFromRecordFilters ||
viewSortsAreDifferentFromRecordSorts ||
viewFilterGroupsAreDifferentFromRecordFilterGroups) &&
!hasFiltersQueryParams;
if (!canShowButton) {
return <></>;
}
return (
<StyledContainer>
{currentView?.key !== 'INDEX' ? (
<ButtonGroup size="small" accent="blue">
<Button title="Update view" onClick={handleUpdateViewClick} />
<Dropdown
dropdownId={UPDATE_VIEW_BUTTON_DROPDOWN_ID}
dropdownHotkeyScope={hotkeyScope}
clickableComponent={
<StyledButton
size="small"
accent="blue"
Icon={IconChevronDown}
position="right"
/>
}
dropdownComponents={
<DropdownMenuItemsContainer>
<MenuItem
onClick={handleCreateViewClick}
LeftIcon={IconPlus}
text={t`Create view`}
/>
</DropdownMenuItemsContainer>
}
/>
</ButtonGroup>
) : (
<Button
title={t`Save as new view`}
onClick={handleSaveAsNewViewClick}
accent="blue"
size="small"
variant="secondary"
/>
)}
</StyledContainer>
);
};