From 17850b76abb4fd0c22fadd06676936a7104a3c47 Mon Sep 17 00:00:00 2001 From: Marie <51697796+ijreilly@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:20:35 +0100 Subject: [PATCH] Aggregate queries follow up (#9581) In this PR - fixing Collapse on view groups views: aggregate bar should be included in the collapse (@magrinj ) - respect the html table pattern: the aggregate bar is now a element included in a (before that, it was a not included in anything) - add a top-border on the aggregate bar - introduce short labels for the on-cell value display (display "Empty" instead of "Count empty" to lighten the interface) - remove the feature flag ! --- .../src/generated-metadata/graphql.ts | 1 - .../twenty-front/src/generated/graphql.tsx | 3 +- .../useRefetchAggregateQueries.test.tsx | 30 +------- .../hooks/useRefetchAggregateQueries.ts | 18 ++--- .../components/RecordBoardColumn.tsx | 1 - .../components/RecordBoardColumnHeader.tsx | 34 ++------- .../RecordBoardColumnHeaderWrapper.tsx | 1 - .../contexts/RecordBoardColumnContext.ts | 1 - ...useAggregateRecordsForRecordBoardColumn.ts | 13 +--- .../computeAggregateValueAndLabel.test.ts | 4 +- .../utils/computeAggregateValueAndLabel.ts | 3 +- .../utils/getAggregateOperationShortLabel.ts | 34 +++++++++ .../record-table/components/RecordTable.tsx | 13 ---- .../RecordTableNoRecordGroupRows.tsx | 9 +++ .../components/RecordTableRecordGroupRows.tsx | 5 ++ .../RecordTableRecordGroupsBody.tsx | 13 ---- .../components/RecordTableAggregateFooter.tsx | 75 +++++++++---------- .../RecordTableAggregateFooterCell.tsx | 3 +- ...egateRecordsForRecordTableColumnFooter.tsx | 8 +- .../components/RecordTableTr.tsx | 4 + .../typeorm-seeds/core/feature-flags.ts | 5 -- ...raphql-query-find-many-resolver.service.ts | 14 ---- .../enums/feature-flag-key.enum.ts | 1 - 23 files changed, 111 insertions(+), 182 deletions(-) create mode 100644 packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/getAggregateOperationShortLabel.ts diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 61b8ce087..21b44ffb0 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -389,7 +389,6 @@ export type FeatureFlagFilter = { export enum FeatureFlagKey { IsAdvancedFiltersEnabled = 'IsAdvancedFiltersEnabled', - IsAggregateQueryEnabled = 'IsAggregateQueryEnabled', IsAirtableIntegrationEnabled = 'IsAirtableIntegrationEnabled', IsAnalyticsV2Enabled = 'IsAnalyticsV2Enabled', IsCommandMenuV2Enabled = 'IsCommandMenuV2Enabled', diff --git a/packages/twenty-front/src/generated/graphql.tsx b/packages/twenty-front/src/generated/graphql.tsx index fa6528523..ae9a2baf9 100644 --- a/packages/twenty-front/src/generated/graphql.tsx +++ b/packages/twenty-front/src/generated/graphql.tsx @@ -1,5 +1,5 @@ -import { gql } from '@apollo/client'; import * as Apollo from '@apollo/client'; +import { gql } from '@apollo/client'; export type Maybe = T | null; export type InputMaybe = Maybe; export type Exact = { [K in keyof T]: T[K] }; @@ -321,7 +321,6 @@ export type FeatureFlagFilter = { export enum FeatureFlagKey { IsAdvancedFiltersEnabled = 'IsAdvancedFiltersEnabled', - IsAggregateQueryEnabled = 'IsAggregateQueryEnabled', IsAirtableIntegrationEnabled = 'IsAirtableIntegrationEnabled', IsAnalyticsV2Enabled = 'IsAnalyticsV2Enabled', IsCommandMenuV2Enabled = 'IsCommandMenuV2Enabled', diff --git a/packages/twenty-front/src/modules/object-record/hooks/__tests__/useRefetchAggregateQueries.test.tsx b/packages/twenty-front/src/modules/object-record/hooks/__tests__/useRefetchAggregateQueries.test.tsx index c8b65a08a..9b54ad301 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/__tests__/useRefetchAggregateQueries.test.tsx +++ b/packages/twenty-front/src/modules/object-record/hooks/__tests__/useRefetchAggregateQueries.test.tsx @@ -1,6 +1,5 @@ import { useRefetchAggregateQueries } from '@/object-record/hooks/useRefetchAggregateQueries'; import { getAggregateQueryName } from '@/object-record/utils/getAggregateQueryName'; -import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { useApolloClient } from '@apollo/client'; import { renderHook } from '@testing-library/react'; @@ -8,16 +7,6 @@ jest.mock('@apollo/client', () => ({ useApolloClient: jest.fn(), })); -jest.mock('@/workspace/hooks/useIsFeatureEnabled', () => ({ - useIsFeatureEnabled: jest.fn(), -})); - -jest.mock('~/generated/graphql', () => ({ - FeatureFlagKey: { - IsAggregateQueryEnabled: 'IsAggregateQueryEnabled', - }, -})); - describe('useRefetchAggregateQueries', () => { const mockRefetchQueries = jest.fn(); const mockApolloClient = { @@ -29,9 +18,8 @@ describe('useRefetchAggregateQueries', () => { (useApolloClient as jest.Mock).mockReturnValue(mockApolloClient); }); - it('should refetch queries when feature flag is enabled', async () => { + it('should refetch queries', async () => { // Arrange - (useIsFeatureEnabled as jest.Mock).mockReturnValue(true); const objectMetadataNamePlural = 'opportunities'; const expectedQueryName = getAggregateQueryName(objectMetadataNamePlural); @@ -48,24 +36,8 @@ describe('useRefetchAggregateQueries', () => { }); }); - it('should not refetch queries when feature flag is disabled', async () => { - // Arrange - (useIsFeatureEnabled as jest.Mock).mockReturnValue(false); - const objectMetadataNamePlural = 'opportunities'; - - // Act - const { result } = renderHook(() => - useRefetchAggregateQueries({ objectMetadataNamePlural }), - ); - await result.current.refetchAggregateQueries(); - - // Assert - expect(mockRefetchQueries).not.toHaveBeenCalled(); - }); - it('should handle errors during refetch', async () => { // Arrange - (useIsFeatureEnabled as jest.Mock).mockReturnValue(true); const error = new Error('Refetch failed'); mockRefetchQueries.mockRejectedValue(error); const objectMetadataNamePlural = 'opportunities'; diff --git a/packages/twenty-front/src/modules/object-record/hooks/useRefetchAggregateQueries.ts b/packages/twenty-front/src/modules/object-record/hooks/useRefetchAggregateQueries.ts index 019a52735..8176af7a7 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useRefetchAggregateQueries.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useRefetchAggregateQueries.ts @@ -1,7 +1,5 @@ import { getAggregateQueryName } from '@/object-record/utils/getAggregateQueryName'; -import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { useApolloClient } from '@apollo/client'; -import { FeatureFlagKey } from '~/generated/graphql'; export const useRefetchAggregateQueries = ({ objectMetadataNamePlural, @@ -9,17 +7,13 @@ export const useRefetchAggregateQueries = ({ objectMetadataNamePlural: string; }) => { const apolloClient = useApolloClient(); - const isAggregateQueryEnabled = useIsFeatureEnabled( - FeatureFlagKey.IsAggregateQueryEnabled, - ); - const refetchAggregateQueries = async () => { - if (isAggregateQueryEnabled) { - const queryName = getAggregateQueryName(objectMetadataNamePlural); - await apolloClient.refetchQueries({ - include: [queryName], - }); - } + const refetchAggregateQueries = async () => { + const queryName = getAggregateQueryName(objectMetadataNamePlural); + + await apolloClient.refetchQueries({ + include: [queryName], + }); }; return { diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumn.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumn.tsx index c76d85c2f..2bde69425 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumn.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumn.tsx @@ -44,7 +44,6 @@ export const RecordBoardColumn = ({ theme.spacing(1)}; `; -const StyledRecordCountChildren = styled.div` - align-items: center; - color: ${({ theme }) => theme.font.color.tertiary}; - display: flex; - height: 24px; - justify-content: center; - line-height: ${({ theme }) => theme.text.lineHeight.lg}; - width: 22px; -`; - const StyledRightContainer = styled.div` align-items: center; display: flex; @@ -103,10 +91,6 @@ export const RecordBoardColumnHeader = () => { columnDefinition.id ?? '', ); - const isAggregateQueryEnabled = useIsFeatureEnabled( - FeatureFlagKey.IsAggregateQueryEnabled, - ); - const { isOpportunitiesCompanyFieldDisabled } = useIsOpportunitiesCompanyFieldDisabled(); @@ -141,18 +125,12 @@ export const RecordBoardColumnHeader = () => { : 'medium' } /> - {isAggregateQueryEnabled ? ( - - ) : ( - - {aggregateValue} - - )} + {isHeaderHovered && ( diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderWrapper.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderWrapper.tsx index c6873baa3..f156395f3 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderWrapper.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderWrapper.tsx @@ -32,7 +32,6 @@ export const RecordBoardColumnHeaderWrapper = ({ value={{ columnId, columnDefinition: recordGroupDefinition, - recordCount: recordIdsByGroup.length, recordIds: recordIdsByGroup, }} > diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext.ts b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext.ts index 1d000084f..4140e0cf1 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext.ts @@ -4,7 +4,6 @@ import { RecordGroupDefinition } from '@/object-record/record-group/types/Record type RecordBoardColumnContextProps = { columnDefinition: RecordGroupDefinition; - recordCount: number; columnId: string; recordIds: string[]; }; diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/hooks/useAggregateRecordsForRecordBoardColumn.ts b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/hooks/useAggregateRecordsForRecordBoardColumn.ts index cdc7248a8..664bf184f 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/hooks/useAggregateRecordsForRecordBoardColumn.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/hooks/useAggregateRecordsForRecordBoardColumn.ts @@ -10,20 +10,12 @@ import { recordIndexKanbanAggregateOperationState } from '@/object-record/record import { recordIndexKanbanFieldMetadataIdState } from '@/object-record/record-index/states/recordIndexKanbanFieldMetadataIdState'; import { recordIndexViewFilterGroupsState } from '@/object-record/record-index/states/recordIndexViewFilterGroupsState'; import { UserContext } from '@/users/contexts/UserContext'; -import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { useContext } from 'react'; import { useRecoilValue } from 'recoil'; -import { FeatureFlagKey } from '~/generated/graphql'; import { isDefined } from '~/utils/isDefined'; export const useAggregateRecordsForRecordBoardColumn = () => { - const isAggregateQueryEnabled = useIsFeatureEnabled( - FeatureFlagKey.IsAggregateQueryEnabled, - ); - - const { columnDefinition, recordCount } = useContext( - RecordBoardColumnContext, - ); + const { columnDefinition } = useContext(RecordBoardColumnContext); const { objectMetadataItem } = useContext(RecordBoardContext); @@ -78,7 +70,6 @@ export const useAggregateRecordsForRecordBoardColumn = () => { objectNameSingular: objectMetadataItem.nameSingular, recordGqlFieldsAggregate, filter, - skip: !isAggregateQueryEnabled, }); const { dateFormat, timeFormat, timeZone } = useContext(UserContext); @@ -95,7 +86,7 @@ export const useAggregateRecordsForRecordBoardColumn = () => { }); return { - aggregateValue: isAggregateQueryEnabled ? value : recordCount, + aggregateValue: value, aggregateLabel: isDefined(value) ? labelWithFieldName : undefined, }; }; diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/__tests__/computeAggregateValueAndLabel.test.ts b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/__tests__/computeAggregateValueAndLabel.test.ts index fab7afaa2..4eed33eb1 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/__tests__/computeAggregateValueAndLabel.test.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/__tests__/computeAggregateValueAndLabel.test.ts @@ -171,7 +171,7 @@ describe('computeAggregateValueAndLabel', () => { }); expect(result).toEqual({ - label: 'Earliest date', + label: 'Earliest', labelWithFieldName: 'Earliest date of Created At', value: '1 Jan, 2023 12:00', }); @@ -207,7 +207,7 @@ describe('computeAggregateValueAndLabel', () => { expect(result).toEqual({ value: '31 Dec, 2023 23:59', - label: 'Latest date', + label: 'Latest', labelWithFieldName: 'Latest date of Updated At', }); }); diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/computeAggregateValueAndLabel.ts b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/computeAggregateValueAndLabel.ts index c348e3532..7753e8bce 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/computeAggregateValueAndLabel.ts +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/computeAggregateValueAndLabel.ts @@ -3,6 +3,7 @@ import { TimeFormat } from '@/localization/constants/TimeFormat'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { AggregateRecordsData } from '@/object-record/hooks/useAggregateRecords'; import { getAggregateOperationLabel } from '@/object-record/record-board/record-board-column/utils/getAggregateOperationLabel'; +import { getAggregateOperationShortLabel } from '@/object-record/record-board/record-board-column/utils/getAggregateOperationShortLabel'; import { AGGREGATE_OPERATIONS } from '@/object-record/record-table/constants/AggregateOperations'; import { COUNT_AGGREGATE_OPERATION_OPTIONS } from '@/object-record/record-table/record-table-footer/constants/countAggregateOperationOptions'; import { PERCENT_AGGREGATE_OPERATION_OPTIONS } from '@/object-record/record-table/record-table-footer/constants/percentAggregateOperationOptions'; @@ -118,7 +119,7 @@ export const computeAggregateValueAndLabel = ({ } } } - const label = getAggregateOperationLabel(aggregateOperation); + const label = getAggregateOperationShortLabel(aggregateOperation); const labelWithFieldName = aggregateOperation === AGGREGATE_OPERATIONS.count ? `${getAggregateOperationLabel(AGGREGATE_OPERATIONS.count)}` diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/getAggregateOperationShortLabel.ts b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/getAggregateOperationShortLabel.ts new file mode 100644 index 000000000..9405acfe9 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/utils/getAggregateOperationShortLabel.ts @@ -0,0 +1,34 @@ +import { AGGREGATE_OPERATIONS } from '@/object-record/record-table/constants/AggregateOperations'; +import { DATE_AGGREGATE_OPERATIONS } from '@/object-record/record-table/constants/DateAggregateOperations'; +import { ExtendedAggregateOperations } from '@/object-record/record-table/types/ExtendedAggregateOperations'; + +export const getAggregateOperationShortLabel = ( + operation: ExtendedAggregateOperations, +) => { + switch (operation) { + case AGGREGATE_OPERATIONS.min: + return 'Min'; + case AGGREGATE_OPERATIONS.max: + return 'Max'; + case AGGREGATE_OPERATIONS.avg: + return 'Average'; + case AGGREGATE_OPERATIONS.sum: + return 'Sum'; + case AGGREGATE_OPERATIONS.count: + return 'All'; + case AGGREGATE_OPERATIONS.countEmpty: + case AGGREGATE_OPERATIONS.percentageEmpty: + return 'Empty'; + case AGGREGATE_OPERATIONS.countNotEmpty: + case AGGREGATE_OPERATIONS.percentageNotEmpty: + return 'Not empty'; + case AGGREGATE_OPERATIONS.countUniqueValues: + return 'Unique'; + case DATE_AGGREGATE_OPERATIONS.earliest: + return 'Earliest'; + case DATE_AGGREGATE_OPERATIONS.latest: + return 'Latest'; + default: + throw new Error(`Unknown aggregate operation: ${operation}`); + } +}; diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx index 571510fcb..4a8fde833 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTable.tsx @@ -13,16 +13,13 @@ import { RecordTableNoRecordGroupBody } from '@/object-record/record-table/recor import { RecordTableNoRecordGroupBodyEffect } from '@/object-record/record-table/record-table-body/components/RecordTableNoRecordGroupBodyEffect'; import { RecordTableRecordGroupBodyEffects } from '@/object-record/record-table/record-table-body/components/RecordTableRecordGroupBodyEffects'; import { RecordTableRecordGroupsBody } from '@/object-record/record-table/record-table-body/components/RecordTableRecordGroupsBody'; -import { RecordTableAggregateFooter } from '@/object-record/record-table/record-table-footer/components/RecordTableAggregateFooter'; import { RecordTableHeader } from '@/object-record/record-table/record-table-header/components/RecordTableHeader'; import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState'; import { hasPendingRecordComponentSelector } from '@/object-record/record-table/states/selectors/hasPendingRecordComponentSelector'; import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect'; import { useClickOutsideListener } from '@/ui/utilities/pointer-event/hooks/useClickOutsideListener'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; -import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { useRef } from 'react'; -import { FeatureFlagKey } from '~/generated/graphql'; const StyledTable = styled.table` border-radius: ${({ theme }) => theme.border.radius.sm}; @@ -36,10 +33,6 @@ export const RecordTable = () => { const tableBodyRef = useRef(null); - const isAggregateQueryEnabled = useIsFeatureEnabled( - FeatureFlagKey.IsAggregateQueryEnabled, - ); - const { toggleClickOutsideListener } = useClickOutsideListener( RECORD_TABLE_CLICK_OUTSIDE_LISTENER_ID, ); @@ -97,12 +90,6 @@ export const RecordTable = () => { )} - {isAggregateQueryEnabled && - !hasRecordGroups && - !isRecordTableInitialLoading && - allRecordIds.length > 0 && ( - - )} { @@ -8,6 +10,10 @@ export const RecordTableNoRecordGroupRows = () => { recordIndexAllRecordIdsComponentSelector, ); + const isRecordTableInitialLoading = useRecoilComponentValueV2( + isRecordTableInitialLoadingComponentState, + ); + return ( <> {allRecordIds.map((recordId, rowIndex) => { @@ -21,6 +27,9 @@ export const RecordTableNoRecordGroupRows = () => { ); })} + {!isRecordTableInitialLoading && allRecordIds.length > 0 && ( + + )} ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableRecordGroupRows.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableRecordGroupRows.tsx index a8907998b..77547999e 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableRecordGroupRows.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableRecordGroupRows.tsx @@ -1,6 +1,7 @@ import { useCurrentRecordGroupId } from '@/object-record/record-group/hooks/useCurrentRecordGroupId'; import { recordIndexRecordIdsByGroupComponentFamilyState } from '@/object-record/record-index/states/recordIndexRecordIdsByGroupComponentFamilyState'; import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector'; +import { RecordTableAggregateFooter } from '@/object-record/record-table/record-table-footer/components/RecordTableAggregateFooter'; import { RecordTablePendingRecordGroupRow } from '@/object-record/record-table/record-table-row/components/RecordTablePendingRecordGroupRow'; import { RecordTableRow } from '@/object-record/record-table/record-table-row/components/RecordTableRow'; import { RecordTableRecordGroupSectionAddNew } from '@/object-record/record-table/record-table-section/components/RecordTableRecordGroupSectionAddNew'; @@ -59,6 +60,10 @@ export const RecordTableRecordGroupRows = () => { + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableRecordGroupsBody.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableRecordGroupsBody.tsx index 0b735ebd2..087019240 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableRecordGroupsBody.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableRecordGroupsBody.tsx @@ -6,14 +6,11 @@ import { RecordTableRecordGroupRows } from '@/object-record/record-table/compone import { RecordTableBodyDroppable } from '@/object-record/record-table/record-table-body/components/RecordTableBodyDroppable'; import { RecordTableBodyLoading } from '@/object-record/record-table/record-table-body/components/RecordTableBodyLoading'; import { RecordTableBodyRecordGroupDragDropContextProvider } from '@/object-record/record-table/record-table-body/components/RecordTableBodyRecordGroupDragDropContextProvider'; -import { RecordTableAggregateFooter } from '@/object-record/record-table/record-table-footer/components/RecordTableAggregateFooter'; import { RecordTableRecordGroupSection } from '@/object-record/record-table/record-table-section/components/RecordTableRecordGroupSection'; import { isRecordTableInitialLoadingComponentState } from '@/object-record/record-table/states/isRecordTableInitialLoadingComponentState'; import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { ViewType } from '@/views/types/ViewType'; -import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; -import { FeatureFlagKey } from '~/generated/graphql'; export const RecordTableRecordGroupsBody = () => { const allRecordIds = useRecoilComponentValueV2( @@ -29,10 +26,6 @@ export const RecordTableRecordGroupsBody = () => { ViewType.Table, ); - const isAggregateQueryEnabled = useIsFeatureEnabled( - FeatureFlagKey.IsAggregateQueryEnabled, - ); - if (isRecordTableInitialLoading && allRecordIds.length === 0) { return ; } @@ -50,12 +43,6 @@ export const RecordTableRecordGroupsBody = () => { - {isAggregateQueryEnabled && ( - - )} ))} diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableAggregateFooter.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableAggregateFooter.tsx index eff130018..99201bd53 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableAggregateFooter.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableAggregateFooter.tsx @@ -8,38 +8,41 @@ import { scrollWrapperInstanceComponentState } from '@/ui/utilities/scroll/state import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { MOBILE_VIEWPORT } from 'twenty-ui'; -const StyledTh = styled.th` +const StyledTd = styled.td` background-color: ${({ theme }) => theme.background.primary}; `; -const StyledTableFoot = styled.thead<{ +const StyledTableRow = styled.tr<{ endOfTableSticky?: boolean; hasHorizontalOverflow?: boolean; }>` + td { + border-top: 1px solid ${({ theme }) => theme.border.color.light}; + } cursor: pointer; - th:nth-of-type(1) { + td:nth-of-type(1) { width: ${FIRST_TH_WIDTH}; left: 0; border-right-color: ${({ theme }) => theme.background.primary}; + border-top: none; } - th:nth-of-type(2) { + td:nth-of-type(2) { border-right-color: ${({ theme }) => theme.background.primary}; - border-top: 1px solid ${({ theme }) => theme.border.color.light}; } &.first-columns-sticky { - th:nth-of-type(1) { + td:nth-of-type(1) { position: sticky; left: 0; z-index: 5; transition: 0.3s ease; } - th:nth-of-type(2) { + td:nth-of-type(2) { position: sticky; left: 11px; z-index: 5; transition: 0.3s ease; } - th:nth-of-type(3) { + td:nth-of-type(3) { position: sticky; left: 43px; z-index: 5; @@ -60,13 +63,12 @@ const StyledTableFoot = styled.thead<{ } } } - tr { - position: sticky; - z-index: 5; - background: ${({ theme }) => theme.background.primary}; - ${({ endOfTableSticky, hasHorizontalOverflow }) => - endOfTableSticky && - ` + position: sticky; + z-index: 5; + background: ${({ theme }) => theme.background.primary}; + ${({ endOfTableSticky, hasHorizontalOverflow }) => + endOfTableSticky && + ` bottom: ${hasHorizontalOverflow ? '10px' : '0'}; ${ hasHorizontalOverflow && @@ -83,7 +85,6 @@ const StyledTableFoot = styled.thead<{ ` } `} - } `; export const RecordTableAggregateFooter = ({ @@ -108,32 +109,30 @@ export const RecordTableAggregateFooter = ({ : false; return ( - - - - - {visibleTableColumns.map((column, index) => { - return ( - - - - ); - })} - - + + + {visibleTableColumns.map((column, index) => { + return ( + + + + ); + })} + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableAggregateFooterCell.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableAggregateFooterCell.tsx index 04b9a51d6..053ba4bec 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableAggregateFooterCell.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableAggregateFooterCell.tsx @@ -9,7 +9,7 @@ import { mapArrayToObject } from '~/utils/array/mapArrayToObject'; const COLUMN_MIN_WIDTH = 104; -const StyledColumnFooterCell = styled.th<{ +const StyledColumnFooterCell = styled.td<{ columnWidth: number; }>` background-color: ${({ theme }) => theme.background.primary}; @@ -43,7 +43,6 @@ const StyledColumnFooterCell = styled.th<{ *::-webkit-scrollbar { display: none; } - border-top: 1px solid ${({ theme }) => theme.border.color.light}; `; const StyledColumnFootContainer = styled.div` diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/hooks/useAggregateRecordsForRecordTableColumnFooter.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/hooks/useAggregateRecordsForRecordTableColumnFooter.tsx index dc8d97e4d..1949bfbda 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/hooks/useAggregateRecordsForRecordTableColumnFooter.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/hooks/useAggregateRecordsForRecordTableColumnFooter.tsx @@ -9,18 +9,13 @@ import { useRecordTableContextOrThrow } from '@/object-record/record-table/conte import { RecordTableColumnAggregateFooterCellContext } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterCellContext'; import { viewFieldAggregateOperationState } from '@/object-record/record-table/record-table-footer/states/viewFieldAggregateOperationState'; import { UserContext } from '@/users/contexts/UserContext'; -import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { useContext } from 'react'; import { useRecoilValue } from 'recoil'; -import { FeatureFlagKey } from '~/generated/graphql'; import { isDefined } from '~/utils/isDefined'; export const useAggregateRecordsForRecordTableColumnFooter = ( fieldMetadataId: string, ) => { - const isAggregateQueryEnabled = useIsFeatureEnabled( - FeatureFlagKey.IsAggregateQueryEnabled, - ); const { objectMetadataItem } = useRecordTableContextOrThrow(); const { recordGroupFilter } = useRecordGroupFilter(objectMetadataItem.fields); @@ -61,8 +56,7 @@ export const useAggregateRecordsForRecordTableColumnFooter = ( objectNameSingular: objectMetadataItem.nameSingular, recordGqlFieldsAggregate, filter: { ...requestFilters, ...recordGroupFilter }, - skip: - !isAggregateQueryEnabled || !isDefined(aggregateOperationForViewField), + skip: !isDefined(aggregateOperationForViewField), }); const { dateFormat, timeFormat, timeZone } = useContext(UserContext); diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableTr.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableTr.tsx index 0ccfc98ac..f7ff0f425 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableTr.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableTr.tsx @@ -6,6 +6,10 @@ const StyledTr = styled.tr<{ isDragging: boolean }>` ? `1px solid ${theme.border.color.medium}` : '1px solid transparent'}; transition: border-left-color 0.2s ease-in-out; + + &:nth-last-child(2) td { + border-bottom: none; + } `; export const RecordTableTr = StyledTr; diff --git a/packages/twenty-server/src/database/typeorm-seeds/core/feature-flags.ts b/packages/twenty-server/src/database/typeorm-seeds/core/feature-flags.ts index 6d77ff67d..673dc0905 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/core/feature-flags.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/core/feature-flags.ts @@ -70,11 +70,6 @@ export const seedFeatureFlags = async ( workspaceId: workspaceId, value: false, }, - { - key: FeatureFlagKey.IsAggregateQueryEnabled, - workspaceId: workspaceId, - value: true, - }, { key: FeatureFlagKey.IsCommandMenuV2Enabled, workspaceId: workspaceId, diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service.ts index 7e3cfc8ac..f0d51e1de 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service.ts @@ -27,7 +27,6 @@ import { getCursor, getPaginationInfo, } from 'src/engine/api/graphql/graphql-query-runner/utils/cursors.util'; -import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; import { isDefined } from 'src/utils/is-defined'; @@ -109,19 +108,6 @@ export class GraphqlQueryFindManyResolverService extends GraphqlQueryBaseResolve appliedFilters, ); - const isAggregationsEnabled = - await this.featureFlagService.isFeatureEnabled( - FeatureFlagKey.IsAggregateQueryEnabled, - authContext.workspace.id, - ); - - if (!isAggregationsEnabled) { - executionArgs.graphqlQuerySelectedFieldsResult.aggregate = { - totalCount: - executionArgs.graphqlQuerySelectedFieldsResult.aggregate.totalCount, - }; - } - const processAggregateHelper = new ProcessAggregateHelper(); processAggregateHelper.addSelectedAggregatedFieldsQueriesToQueryBuilder({ diff --git a/packages/twenty-server/src/engine/core-modules/feature-flag/enums/feature-flag-key.enum.ts b/packages/twenty-server/src/engine/core-modules/feature-flag/enums/feature-flag-key.enum.ts index 46988b824..c15b30e4e 100644 --- a/packages/twenty-server/src/engine/core-modules/feature-flag/enums/feature-flag-key.enum.ts +++ b/packages/twenty-server/src/engine/core-modules/feature-flag/enums/feature-flag-key.enum.ts @@ -12,7 +12,6 @@ export enum FeatureFlagKey { IsUniqueIndexesEnabled = 'IS_UNIQUE_INDEXES_ENABLED', IsMicrosoftSyncEnabled = 'IS_MICROSOFT_SYNC_ENABLED', IsAdvancedFiltersEnabled = 'IS_ADVANCED_FILTERS_ENABLED', - IsAggregateQueryEnabled = 'IS_AGGREGATE_QUERY_ENABLED', IsCommandMenuV2Enabled = 'IS_COMMAND_MENU_V2_ENABLED', IsCrmMigrationEnabled = 'IS_CRM_MIGRATION_ENABLED', IsJsonFilterEnabled = 'IS_JSON_FILTER_ENABLED',