From 843aab7447cfaff28971bb68cee9e9b5db444ed1 Mon Sep 17 00:00:00 2001 From: Mateusz Kwasniewski Date: Tue, 7 May 2024 14:44:09 +0200 Subject: [PATCH] fix: remove columns from the search api query (#6996) --- .../OldProjectFeatureToggles.tsx | 495 ------------------ .../ProjectFeatureToggles.tsx | 6 +- 2 files changed, 3 insertions(+), 498 deletions(-) delete mode 100644 frontend/src/component/project/Project/PaginatedProjectFeatureToggles/OldProjectFeatureToggles.tsx diff --git a/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/OldProjectFeatureToggles.tsx b/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/OldProjectFeatureToggles.tsx deleted file mode 100644 index 80e8860d4fe..00000000000 --- a/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/OldProjectFeatureToggles.tsx +++ /dev/null @@ -1,495 +0,0 @@ -import { useCallback, useMemo, useState } from 'react'; -import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; -import { PageContent } from 'component/common/PageContent/PageContent'; -import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; -import { DateCell } from 'component/common/Table/cells/DateCell/DateCell'; -import { FeatureTypeCell } from 'component/common/Table/cells/FeatureTypeCell/FeatureTypeCell'; -import { PaginatedTable } from 'component/common/Table'; -import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; -import { FavoriteIconHeader } from 'component/common/Table/FavoriteIconHeader/FavoriteIconHeader'; -import { FavoriteIconCell } from 'component/common/Table/cells/FavoriteIconCell/FavoriteIconCell'; -import { ActionsCell } from '../ProjectFeatureToggles/ActionsCell/ActionsCell'; -import { ExperimentalColumnsMenu as ColumnsMenu } from './ExperimentalColumnsMenu/ExperimentalColumnsMenu'; -import { useFavoriteFeaturesApi } from 'hooks/api/actions/useFavoriteFeaturesApi/useFavoriteFeaturesApi'; -import { ExportDialog } from 'component/feature/FeatureToggleList/ExportDialog'; -import { MemoizedRowSelectCell } from '../ProjectFeatureToggles/RowSelectCell/RowSelectCell'; -import { BatchSelectionActionsBar } from 'component/common/BatchSelectionActionsBar/BatchSelectionActionsBar'; -import { ProjectFeaturesBatchActions } from '../ProjectFeatureToggles/ProjectFeaturesBatchActions/ProjectFeaturesBatchActions'; -import { MemoizedFeatureEnvironmentSeenCell } from 'component/common/Table/cells/FeatureSeenCell/FeatureEnvironmentSeenCell'; -import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled'; -import { useFeatureToggleSwitch } from '../ProjectFeatureToggles/FeatureToggleSwitch/useFeatureToggleSwitch'; -import useLoading from 'hooks/useLoading'; -import { - DEFAULT_PAGE_LIMIT, - useFeatureSearch, -} from 'hooks/api/getters/useFeatureSearch/useFeatureSearch'; -import mapValues from 'lodash.mapvalues'; -import { usePersistentTableState } from 'hooks/usePersistentTableState'; -import { - BooleansStringParam, - FilterItemParam, -} from 'utils/serializeQueryParams'; -import { - NumberParam, - StringParam, - ArrayParam, - withDefault, - encodeQueryParams, -} from 'use-query-params'; -import { ProjectFeatureTogglesHeader } from './ProjectFeatureTogglesHeader/ProjectFeatureTogglesHeader'; -import { createColumnHelper, useReactTable } from '@tanstack/react-table'; -import { withTableState } from 'utils/withTableState'; -import type { FeatureSearchResponseSchema } from 'openapi'; -import { FeatureNameCell } from 'component/common/Table/cells/FeatureNameCell/FeatureNameCell'; -import { FeatureToggleCell } from './FeatureToggleCell/FeatureToggleCell'; -import { ProjectOverviewFilters } from './ProjectOverviewFilters'; -import { useDefaultColumnVisibility } from './hooks/useDefaultColumnVisibility'; -import { TableEmptyState } from './TableEmptyState/TableEmptyState'; -import { useRowActions } from './hooks/useRowActions'; -import { useUiFlag } from 'hooks/useUiFlag'; -import { FeatureTagCell } from 'component/common/Table/cells/FeatureTagCell/FeatureTagCell'; -import { useSelectedData } from './hooks/useSelectedData'; - -interface IPaginatedProjectFeatureTogglesProps { - environments: string[]; - refreshInterval?: number; - storageKey?: string; -} - -const formatEnvironmentColumnId = (environment: string) => - `environment:${environment}`; - -const columnHelper = createColumnHelper(); -const getRowId = (row: { name: string }) => row.name; - -export const OldProjectFeatureToggles = ({ - environments, - refreshInterval = 15 * 1000, - storageKey = 'project-feature-toggles-v2', -}: IPaginatedProjectFeatureTogglesProps) => { - const projectId = useRequiredPathParam('projectId'); - - const featuresExportImport = useUiFlag('featuresExportImport'); - - const stateConfig = { - offset: withDefault(NumberParam, 0), - limit: withDefault(NumberParam, DEFAULT_PAGE_LIMIT), - query: StringParam, - favoritesFirst: withDefault(BooleansStringParam, true), - sortBy: withDefault(StringParam, 'createdAt'), - sortOrder: withDefault(StringParam, 'desc'), - columns: ArrayParam, - tag: FilterItemParam, - createdAt: FilterItemParam, - }; - const [tableState, setTableState] = usePersistentTableState( - `${storageKey}-${projectId}`, - stateConfig, - ); - - const filterState = { - tag: tableState.tag, - createdAt: tableState.createdAt, - }; - - const { features, total, refetch, loading, initialLoad } = useFeatureSearch( - mapValues( - { - ...encodeQueryParams(stateConfig, tableState), - project: `IS:${projectId}`, - }, - (value) => (value ? `${value}` : undefined), - ), - { - refreshInterval, - }, - ); - - const { favorite, unfavorite } = useFavoriteFeaturesApi(); - const onFavorite = useCallback( - async (feature: FeatureSearchResponseSchema) => { - if (feature?.favorite) { - await unfavorite(projectId, feature.name); - } else { - await favorite(projectId, feature.name); - } - refetch(); - }, - [projectId, refetch], - ); - const { isChangeRequestConfigured } = useChangeRequestsEnabled(projectId); - const { onToggle: onFeatureToggle, modals: featureToggleModals } = - useFeatureToggleSwitch(projectId); - const { - rowActionsDialogs, - setFeatureArchiveState, - setFeatureStaleDialogState, - } = useRowActions(refetch, projectId); - const [showExportDialog, setShowExportDialog] = useState(false); - - const columns = useMemo( - () => [ - columnHelper.display({ - id: 'select', - header: ({ table }) => ( - - ), - cell: ({ row }) => ( - - ), - meta: { - width: '1%', - }, - enableHiding: false, - }), - columnHelper.accessor('favorite', { - id: 'favorite', - header: () => ( - - setTableState({ - favoritesFirst: !tableState.favoritesFirst, - }) - } - /> - ), - cell: ({ row: { original: feature } }) => ( - onFavorite(feature)} - /> - ), - enableSorting: false, - enableHiding: false, - meta: { - align: 'center', - width: '1%', - }, - }), - columnHelper.accessor('lastSeenAt', { - id: 'lastSeenAt', - header: 'Last seen', - cell: ({ row: { original } }) => ( - - ), - size: 50, - meta: { - align: 'center', - width: '1%', - }, - }), - columnHelper.accessor('type', { - id: 'type', - header: 'Type', - cell: FeatureTypeCell, - meta: { - align: 'center', - width: '1%', - }, - }), - columnHelper.accessor('name', { - id: 'name', - header: 'Name', - cell: FeatureNameCell, - enableHiding: false, - meta: { - width: '50%', - }, - }), - columnHelper.accessor('tags', { - id: 'tags', - header: 'Tags', - enableSorting: false, - cell: FeatureTagCell, - meta: { - width: '1%', - }, - }), - columnHelper.accessor('createdAt', { - id: 'createdAt', - header: 'Created', - cell: DateCell, - }), - ...environments.map((name: string) => { - const isChangeRequestEnabled = isChangeRequestConfigured(name); - - return columnHelper.accessor( - (row) => ({ - featureId: row.name, - environment: row.environments?.find( - (featureEnvironment) => - featureEnvironment.name === name, - ), - someEnabledEnvironmentHasVariants: - row.environments?.some( - (featureEnvironment) => - featureEnvironment.variantCount && - featureEnvironment.variantCount > 0 && - featureEnvironment.enabled, - ) || false, - }), - { - id: formatEnvironmentColumnId(name), - header: name, - meta: { - align: 'center', - width: 90, - }, - cell: ({ getValue }) => { - const { - featureId, - environment, - someEnabledEnvironmentHasVariants, - } = getValue(); - - return ( - - ); - }, - }, - ); - }), - columnHelper.display({ - id: 'actions', - header: '', - cell: ({ row }) => ( - - ), - enableSorting: false, - enableHiding: false, - meta: { - align: 'right', - width: '1%', - }, - }), - ], - [projectId, environments, tableState.favoritesFirst, refetch], - ); - - const placeholderData = useMemo( - () => - Array(tableState.limit) - .fill(null) - .map((_, index) => ({ - id: index, - type: '-', - name: `Feature name ${index}`, - createdAt: new Date().toISOString(), - dependencyType: null, - favorite: false, - impressionData: false, - project: 'project', - segments: [], - stale: false, - environments: [ - { - name: 'production', - enabled: false, - }, - { - name: 'production', - enabled: false, - }, - ], - })), - [tableState.limit], - ); - - const isPlaceholder = Boolean(initialLoad || (loading && total)); - const bodyLoadingRef = useLoading(isPlaceholder); - - const data = useMemo(() => { - if (isPlaceholder) { - return placeholderData; - } - return features; - }, [isPlaceholder, features]); - const allColumnIds = useMemo( - () => columns.map((column) => column.id).filter(Boolean) as string[], - [columns], - ); - - const defaultColumnVisibility = useDefaultColumnVisibility(allColumnIds); - - const table = useReactTable( - withTableState(tableState, setTableState, { - columns, - data, - enableRowSelection: true, - state: { - columnVisibility: defaultColumnVisibility, - }, - getRowId, - }), - ); - - const { columnVisibility, rowSelection } = table.getState(); - const onToggleColumnVisibility = useCallback( - (columnId) => { - const isVisible = columnVisibility[columnId]; - const newColumnVisibility: Record = { - ...columnVisibility, - [columnId]: !isVisible, - }; - setTableState({ - columns: Object.keys(newColumnVisibility).filter( - (columnId) => - newColumnVisibility[columnId] && - !columnId.includes(','), - ), - }); - }, - [columnVisibility, setTableState], - ); - - const selectedData = useSelectedData(features, rowSelection); - - return ( - <> - { - setTableState({ query }); - }} - dataToExport={data} - environmentsToExport={environments} - actions={ - ({ - header: environment, - id: formatEnvironmentColumnId( - environment, - ), - isVisible: - columnVisibility[ - formatEnvironmentColumnId( - environment, - ) - ], - })), - ]} - onToggle={onToggleColumnVisibility} - /> - } - /> - } - bodyClass='noop' - style={{ cursor: 'inherit' }} - > -
- - - - - - } - /> - {rowActionsDialogs} - - setShowExportDialog(false)} - environments={environments} - /> - } - /> - {featureToggleModals} -
-
- - - - - ); -}; diff --git a/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx b/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx index b8489ad74f4..280e2f1de05 100644 --- a/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx +++ b/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx @@ -1,4 +1,4 @@ -import { useCallback, useMemo, useState } from 'react'; +import { useCallback, useMemo } from 'react'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { PageContent } from 'component/common/PageContent/PageContent'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; @@ -86,10 +86,11 @@ export const ProjectFeatureToggles = ({ createdAt: tableState.createdAt, }; + const { columns: _, ...apiTableState } = tableState; const { features, total, refetch, loading, initialLoad } = useFeatureSearch( mapValues( { - ...encodeQueryParams(stateConfig, tableState), + ...encodeQueryParams(stateConfig, apiTableState), project: `IS:${projectId}`, }, (value) => (value ? `${value}` : undefined), @@ -119,7 +120,6 @@ export const ProjectFeatureToggles = ({ setFeatureArchiveState, setFeatureStaleDialogState, } = useRowActions(refetch, projectId); - const [showExportDialog, setShowExportDialog] = useState(false); const columns = useMemo( () => [