From 6df366e0cfd5f1e370be1a4eec6acb95bca39703 Mon Sep 17 00:00:00 2001 From: Alex Boungnaseng Date: Wed, 20 Nov 2024 19:21:20 +0100 Subject: [PATCH] feat(manager-react-components): add filters in datagrid ref: MANAGER-15088 Signed-off-by: Alex Boungnaseng --- .../datagrid/datagrid-cursor.stories.tsx | 38 +++++----- .../datagrid/datagrid.component.tsx | 74 ++++++++++++++++++- .../src/components/datagrid/datagrid.spec.tsx | 51 ++++++++++++- .../components/datagrid/datagrid.stories.tsx | 45 ++++++++++- .../filters/filter-add.component.tsx | 44 +++++++---- .../src/hooks/datagrid/useIcebergV2.spec.tsx | 29 +++++++- .../src/hooks/datagrid/useIcebergV2.tsx | 21 +++++- .../src/hooks/datagrid/useIcebergV6.tsx | 11 ++- .../hooks/datagrid/useResourcesV6.spec.tsx | 40 +++++++++- .../src/hooks/datagrid/useResourcesV6.tsx | 20 +++-- .../listing/v2/index.tsx.hbs | 20 ++++- .../listing/v6/index.tsx.hbs | 20 ++++- 12 files changed, 353 insertions(+), 60 deletions(-) diff --git a/packages/manager-react-components/src/components/datagrid/datagrid-cursor.stories.tsx b/packages/manager-react-components/src/components/datagrid/datagrid-cursor.stories.tsx index 3d72b96065b8..56b2d5fda513 100644 --- a/packages/manager-react-components/src/components/datagrid/datagrid-cursor.stories.tsx +++ b/packages/manager-react-components/src/components/datagrid/datagrid-cursor.stories.tsx @@ -1,42 +1,30 @@ import React, { useState } from 'react'; import { ColumnSort } from '@tanstack/react-table'; import { withRouter } from 'storybook-addon-react-router-v6'; +import { applyFilters } from '@ovh-ux/manager-core-api'; import { useSearchParams } from 'react-router-dom'; import { Datagrid } from './datagrid.component'; -import { DataGridTextCell } from './text-cell.component'; +import { useColumnFilters } from '../filters'; +import { columsTmp, columsFilters } from './datagrid.stories'; interface Item { label: string; price: number; } -const columns = [ - { - id: 'label', - cell: (item: Item) => { - return {item.label}; - }, - label: 'Label', - }, - { - id: 'price', - cell: (item: Item) => { - return {item.price} €; - }, - label: 'Price', - }, -]; - const DatagridStory = ({ items, isSortable, + columns = columsTmp, }: { items: Item[]; isSortable: boolean; + columns?: any; }) => { const [sorting, setSorting] = useState(); const [data, setData] = useState(items); const [searchParams] = useSearchParams(); + const { filters, addFilter, removeFilter } = useColumnFilters(); const fetchNextPage = () => { const itemsIndex = data.length; @@ -57,10 +45,11 @@ const DatagridStory = ({ )} 0 && data.length < 30} onFetchNextPage={fetchNextPage} + filters={{ filters: filters, add: addFilter, remove: removeFilter }} {...(isSortable ? { sorting, @@ -99,6 +88,17 @@ export const Sortable = { }, }; +export const Filters = { + args: { + items: [...Array(10).keys()].map((_, i) => ({ + label: `Item #${i}`, + price: Math.floor(1 + Math.random() * 100), + })), + isSortable: true, + columns: columsFilters, + }, +}; + export default { title: 'Components/Datagrid Cursor', component: DatagridStory, diff --git a/packages/manager-react-components/src/components/datagrid/datagrid.component.tsx b/packages/manager-react-components/src/components/datagrid/datagrid.component.tsx index 9f7404855228..aac65fc56c70 100644 --- a/packages/manager-react-components/src/components/datagrid/datagrid.component.tsx +++ b/packages/manager-react-components/src/components/datagrid/datagrid.component.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { ColumnDef, ColumnSort as TanstackColumnSort, @@ -8,15 +8,23 @@ import { useReactTable, getSortedRowModel, } from '@tanstack/react-table'; -import { ODS_ICON_NAME, ODS_BUTTON_VARIANT } from '@ovhcloud/ods-components'; import { + ODS_ICON_NAME, + ODS_BUTTON_VARIANT, + ODS_BUTTON_SIZE, +} from '@ovhcloud/ods-components'; +import { + OdsPopover, OdsButton, OdsIcon, OdsPagination, OdsTable, } from '@ovhcloud/ods-components/react'; import { useTranslation } from 'react-i18next'; +import { FilterAdd, FilterList } from '../filters'; +import { FilterWithLabel } from '../filters/interface'; import { DataGridTextCell } from './text-cell.component'; +import { FilterComparator } from '@ovh-ux/manager-core-api'; import './translations'; export type ColumnSort = TanstackColumnSort; @@ -35,6 +43,21 @@ export interface DatagridColumn { label: string; /** is the column sortable ? (defaults is true) */ isSortable?: boolean; + /** set column filter */ + comparator?: FilterComparator; +} + +type ColumnFilterProps = { + key: string; + value: string | string[]; + comparator: FilterComparator; + label: string; +}; + +export interface FilterProps { + filters: FilterWithLabel[]; + add: (filters: ColumnFilterProps) => void; + remove: (filter: FilterWithLabel) => void; } export interface DatagridProps { @@ -68,6 +91,7 @@ export interface DatagridProps { /** setSorting?: OnChangeFn; */ /** label displayed if there is no item in the datagrid */ noResultLabel?: string; + filters?: FilterProps; } export const Datagrid = ({ @@ -85,6 +109,7 @@ export const Datagrid = ({ manualSorting = true, manualPagination = true, noResultLabel, + filters, }: DatagridProps) => { const { t } = useTranslation('datagrid'); const pageCount = pagination @@ -131,8 +156,53 @@ export const Datagrid = ({ }), }); + const [columnsFilters, setColumnsFilters] = useState([]); + useEffect(() => { + const clmFilters = columns + .filter((item) => 'comparator' in item) + .map((column) => ({ + id: column.id, + label: column.label, + comparators: column.comparator, + })); + setColumnsFilters(clmFilters); + }, [columns]); + return (
+ {columnsFilters.length > 0 && ( +
+
+ +
+ + { + filters.add({ + ...addedFilter, + label: column.label, + }); + }} + /> + +
+ )} + {filters?.filters && ( +
+ +
+ )} +
diff --git a/packages/manager-react-components/src/components/datagrid/datagrid.spec.tsx b/packages/manager-react-components/src/components/datagrid/datagrid.spec.tsx index 945686b4d252..3278bf502591 100644 --- a/packages/manager-react-components/src/components/datagrid/datagrid.spec.tsx +++ b/packages/manager-react-components/src/components/datagrid/datagrid.spec.tsx @@ -1,11 +1,12 @@ import { vitest } from 'vitest'; import React, { useState } from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; +import { FilterCategories } from '@ovh-ux/manager-core-api'; import { ColumnSort, Datagrid, - DatagridColumn, PaginationState, + FilterProps, } from './datagrid.component'; import DataGridTextCell from './text-cell.component'; @@ -32,11 +33,13 @@ const sampleColumns = [ return {name}; }, label: 'Name', + comparator: FilterCategories.String, }, { id: 'another-column', label: 'test', cell: () => , + comparator: FilterCategories.String, }, ]; @@ -46,12 +49,14 @@ const DatagridTest = ({ pageIndex, className, noResultLabel, + filters, }: { - columns: DatagridColumn[]; + columns: any; items: string[]; pageIndex: number; className?: string; noResultLabel?: string; + filters?: FilterProps; }) => { const [pagination, setPagination] = useState({ pageIndex, @@ -70,6 +75,7 @@ const DatagridTest = ({ onSortChange={() => {}} className={className || ''} noResultLabel={noResultLabel} + filters={filters} /> ); }; @@ -220,3 +226,44 @@ it('should disable overflow of table', async () => { ); expect(container.querySelectorAll('.overflow-hidden').length).toBe(1); }); + +it('should disable overflow of table', async () => { + const { container } = render( + , + ); + expect(container.querySelectorAll('.overflow-hidden').length).toBe(1); +}); + +it('should display filter add and filter list', async () => { + const filters = { + filters: [ + { + key: 'customName', + comparator: 'includes', + value: 'coucou', + label: 'customName', + }, + ], + add: null, + remove: null, + } as FilterProps; + console.info('sampleColumns : ', sampleColumns); + const { container } = render( + , + ); + expect( + container.querySelectorAll('#datagrid-filter-popover-trigger').length, + ).toBe(1); + expect(container.querySelectorAll('#datagrid-filter-list').length).toBe(1); +}); diff --git a/packages/manager-react-components/src/components/datagrid/datagrid.stories.tsx b/packages/manager-react-components/src/components/datagrid/datagrid.stories.tsx index 582934f980fa..c44166f899df 100644 --- a/packages/manager-react-components/src/components/datagrid/datagrid.stories.tsx +++ b/packages/manager-react-components/src/components/datagrid/datagrid.stories.tsx @@ -1,16 +1,18 @@ import React from 'react'; import { withRouter } from 'storybook-addon-react-router-v6'; import { useSearchParams } from 'react-router-dom'; +import { FilterCategories, applyFilters } from '@ovh-ux/manager-core-api'; import { Datagrid } from './datagrid.component'; import { DataGridTextCell } from './text-cell.component'; import { useDatagridSearchParams } from './useDatagridSearchParams'; +import { useColumnFilters } from '../filters'; interface Item { label: string; price: number; } -const columns = [ +export const columsTmp = [ { id: 'label', cell: (item: Item) => { @@ -27,6 +29,25 @@ const columns = [ }, ]; +export const columsFilters = [ + { + id: 'label', + cell: (item: Item) => { + return {item.label}; + }, + label: 'Label', + comparator: FilterCategories.String, + }, + { + id: 'price', + cell: (item: Item) => { + return {item.price} €; + }, + label: 'Price', + comparator: FilterCategories.String, + }, +]; + function sortItems( itemList: Item[], sorting: { id: string; desc: boolean }, @@ -44,10 +65,12 @@ const DatagridStory = ({ items, isPaginated, isSortable, + columns = columsTmp, }: { items: Item[]; isPaginated: boolean; isSortable: boolean; + columns?: any; }) => { const [searchParams] = useSearchParams(); const { pagination, setPagination, sorting, setSorting } = @@ -65,6 +88,8 @@ const DatagridStory = ({ sorting, onSortChange: setSorting, }; + const { filters, addFilter, removeFilter } = useColumnFilters(); + return ( <> {`${searchParams}` && ( @@ -75,10 +100,14 @@ const DatagridStory = ({ )} ); @@ -120,6 +149,18 @@ export const Pagination = { }, }; +export const Filters = { + args: { + items: [...Array(50).keys()].map((_, i) => ({ + label: `Item #${i}`, + price: Math.floor(1 + Math.random() * 100), + })), + isPaginated: true, + isSortable: true, + columns: columsFilters, + }, +}; + export default { title: 'Components/Datagrid Paginated', component: DatagridStory, diff --git a/packages/manager-react-components/src/components/filters/filter-add.component.tsx b/packages/manager-react-components/src/components/filters/filter-add.component.tsx index e2865284a3e5..c0feb086479a 100644 --- a/packages/manager-react-components/src/components/filters/filter-add.component.tsx +++ b/packages/manager-react-components/src/components/filters/filter-add.component.tsx @@ -1,4 +1,4 @@ -import React, { useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import { Filter, FilterComparator } from '@ovh-ux/manager-core-api'; import { ODS_BUTTON_SIZE, ODS_INPUT_TYPE } from '@ovhcloud/ods-components'; @@ -48,6 +48,10 @@ export function FilterAdd({ columns, onAddFilter }: Readonly) { setValue(''); }; + useEffect(() => { + setSelectedComparator(selectedColumn?.comparators[0]); + }, [selectedColumn]); + return ( <>
@@ -78,19 +82,31 @@ export function FilterAdd({ columns, onAddFilter }: Readonly) { {t('common_criteria_adder_operator_label')}
- { - setSelectedComparator(event.detail.value as FilterComparator); - }} - > - {selectedColumn?.comparators?.map((comp) => ( - - ))} - + {selectedColumn && + columns.map((column) => { + return ( +
+ { + setSelectedComparator( + event.detail.value as FilterComparator, + ); + }} + > + {column?.comparators?.map((comp) => ( + + ))} + +
+ ); + })}
diff --git a/packages/manager-react-components/src/hooks/datagrid/useIcebergV2.spec.tsx b/packages/manager-react-components/src/hooks/datagrid/useIcebergV2.spec.tsx index 9ad165aac11d..8c5c9d902f4b 100644 --- a/packages/manager-react-components/src/hooks/datagrid/useIcebergV2.spec.tsx +++ b/packages/manager-react-components/src/hooks/datagrid/useIcebergV2.spec.tsx @@ -5,7 +5,8 @@ import { QueryClientProvider, useInfiniteQuery, } from '@tanstack/react-query'; -import { renderHook } from '@testing-library/react'; +import { FilterComparator } from '@ovh-ux/manager-core-api'; +import { renderHook, act, waitFor } from '@testing-library/react'; import { useResourcesIcebergV2 } from './useIcebergV2'; vitest.mock('@tanstack/react-query', async () => { @@ -47,7 +48,7 @@ const mockData = { }, { ip: '15.235.xxx.xxx', - newUpgradeSystem: true, + newUpgradeSystem: false, }, { ip: '148.113.xxx.xxx', @@ -74,7 +75,7 @@ const mockData = { newUpgradeSystem: true, }, { - ip: '15.235.xxx.xxx', + ip: '15.234.xxx.xxx', newUpgradeSystem: true, }, { @@ -112,4 +113,26 @@ describe('useIcebergV2', () => { const { hasNextPage } = result.current; expect(hasNextPage).toBeTruthy(); }); + + it('should match 15.235.xxx.xxx with a filter ip', async () => { + const result = renderUseIcebergV2Hook(); + act(() => { + result.current.filters.add({ + comparator: 'includes' as FilterComparator, + key: 'ip', + value: '15.235', + label: 'ip', + }); + }); + waitFor(() => { + const { flattenData, filters } = result.current; + expect(flattenData.length).toBe(1); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + expect(flattenData[0].ip).toBe('15.235.xxx.xxx'); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + expect(filters.value).toBe(15.235); + }); + }); }); diff --git a/packages/manager-react-components/src/hooks/datagrid/useIcebergV2.tsx b/packages/manager-react-components/src/hooks/datagrid/useIcebergV2.tsx index deb1224019fc..a6507c34d219 100644 --- a/packages/manager-react-components/src/hooks/datagrid/useIcebergV2.tsx +++ b/packages/manager-react-components/src/hooks/datagrid/useIcebergV2.tsx @@ -1,7 +1,11 @@ import { useEffect, useState } from 'react'; -import { IcebergFetchParamsV2, fetchIcebergV2 } from '@ovh-ux/manager-core-api'; +import { + IcebergFetchParamsV2, + fetchIcebergV2, + applyFilters, +} from '@ovh-ux/manager-core-api'; import { useInfiniteQuery } from '@tanstack/react-query'; -import { ColumnSort } from '../../components'; +import { useColumnFilters, ColumnSort } from '../../components'; interface IcebergV2Hook { queryKey: string[]; @@ -41,12 +45,20 @@ export function useResourcesIcebergV2({ retry: false, getNextPageParam: (lastPage) => lastPage.cursorNext, }); + const { filters, addFilter, removeFilter } = useColumnFilters(); useEffect(() => { const flatten = data?.pages.map((page) => page.data).flat() as T[]; setFlattenData(flatten); }, [data]); + useEffect(() => { + if (flattenData.length > 0) { + const flatten = data?.pages.map((page) => page.data).flat() as T[]; + setFlattenData(applyFilters(flatten, filters)); + } + }, [filters]); + return { data, fetchNextPage, @@ -58,5 +70,10 @@ export function useResourcesIcebergV2({ sorting, error, status, + filters: { + filters, + add: addFilter, + remove: removeFilter, + }, }; } diff --git a/packages/manager-react-components/src/hooks/datagrid/useIcebergV6.tsx b/packages/manager-react-components/src/hooks/datagrid/useIcebergV6.tsx index 8b75b4c6c474..c465d240ca3b 100644 --- a/packages/manager-react-components/src/hooks/datagrid/useIcebergV6.tsx +++ b/packages/manager-react-components/src/hooks/datagrid/useIcebergV6.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import { IcebergFetchParamsV6, fetchIcebergV6 } from '@ovh-ux/manager-core-api'; import { useInfiniteQuery } from '@tanstack/react-query'; -import { ColumnSort } from '../../components'; +import { useColumnFilters, ColumnSort } from '../../components'; interface IcebergV6Hook { queryKey: string[]; @@ -20,10 +20,11 @@ export function useResourcesIcebergV6({ defaultSorting = undefined, }: IcebergFetchParamsV6 & IcebergV6Hook) { const [sorting, setSorting] = useState(defaultSorting); + const { filters, addFilter, removeFilter } = useColumnFilters(); const { data: dataSelected, ...rest } = useInfiniteQuery({ initialPageParam: 1, - queryKey: [...queryKey, pageSize, sorting], + queryKey: [...queryKey, pageSize, sorting, filters], staleTime: Infinity, retry: false, queryFn: ({ pageParam: pageIndex }) => @@ -33,6 +34,7 @@ export function useResourcesIcebergV6({ page: pageIndex, sortBy: sorting?.id || null, sortReverse: sorting?.desc, + filters, }), getNextPageParam: (lastPage, _allPages, lastPageIndex) => { if (lastPage.totalCount / pageSize > lastPageIndex) { @@ -58,5 +60,10 @@ export function useResourcesIcebergV6({ ...rest, sorting, setSorting, + filters: { + filters, + add: addFilter, + remove: removeFilter, + }, }; } diff --git a/packages/manager-react-components/src/hooks/datagrid/useResourcesV6.spec.tsx b/packages/manager-react-components/src/hooks/datagrid/useResourcesV6.spec.tsx index 16e94c277142..6e91ac0db5e5 100644 --- a/packages/manager-react-components/src/hooks/datagrid/useResourcesV6.spec.tsx +++ b/packages/manager-react-components/src/hooks/datagrid/useResourcesV6.spec.tsx @@ -5,8 +5,12 @@ import { QueryClientProvider, useQuery, } from '@tanstack/react-query'; -import { act, renderHook } from '@testing-library/react'; -import { IcebergFetchParamsV6 } from '@ovh-ux/manager-core-api'; +import { act, renderHook, waitFor } from '@testing-library/react'; +import { + IcebergFetchParamsV6, + FilterCategories, + FilterComparator, +} from '@ovh-ux/manager-core-api'; import { ResourcesV6Hook, useResourcesV6 } from './useResourcesV6'; vitest.mock('@tanstack/react-query', async () => { @@ -32,6 +36,16 @@ const renderUseResourcesV6Hook = ( header: 'name', label: 'name', accessorKey: 'name', + comparator: FilterCategories.String, + type: 'string', + cell: (props: any) =>
{props.name}
, + }, + { + id: 'name2', + header: 'name2', + label: 'name2', + accessorKey: 'name2', + comparator: FilterCategories.String, type: 'string', cell: (props: any) =>
{props.name}
, }, @@ -110,4 +124,26 @@ describe('useResourcesV6', () => { const { totalCount } = result.current; expect(totalCount).toEqual(26); }); + + it('should match ip-51-7 with a filter name', async () => { + const { result } = renderUseResourcesV6Hook(); + act(() => { + result.current.filters.add({ + comparator: 'includes' as FilterComparator, + key: 'name', + value: 'ns5007027.ip-51-7-XXXXX5.net', + label: 'name', + }); + }); + waitFor(() => { + const { flattenData, filters } = result.current; + expect(flattenData.length).toBe(1); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + expect(flattenData[0].name).toBe('ns5007027.ip-51-7-XXXXX5.net'); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + expect(filters.value).toBe('ns5007027.ip-51-7-XXXXX5.net'); + }); + }); }); diff --git a/packages/manager-react-components/src/hooks/datagrid/useResourcesV6.tsx b/packages/manager-react-components/src/hooks/datagrid/useResourcesV6.tsx index 30364230937b..89518e8c0106 100644 --- a/packages/manager-react-components/src/hooks/datagrid/useResourcesV6.tsx +++ b/packages/manager-react-components/src/hooks/datagrid/useResourcesV6.tsx @@ -1,8 +1,12 @@ import React, { useState, useEffect } from 'react'; import isDate from 'lodash.isdate'; -import { IcebergFetchParamsV6, fetchIcebergV6 } from '@ovh-ux/manager-core-api'; +import { + IcebergFetchParamsV6, + fetchIcebergV6, + applyFilters, +} from '@ovh-ux/manager-core-api'; import { useQuery } from '@tanstack/react-query'; -import { ColumnSort } from '../../components'; +import { useColumnFilters, ColumnSort } from '../../components'; export interface ColumnDatagrid { cell: (props: any) => React.JSX.Element; @@ -54,10 +58,6 @@ function sortColumn(type: string, a: any, b: any, desc: boolean) { * @deprecated use fetchIcebergV6 from @ovh-ux/manager-core-api */ export const getResourcesV6 = fetchIcebergV6; -// export const getResourcesV6 = async ({ route }: IcebergFetchParamsV6) => { -// const { data, status, totalCount } = (await fetchIcebergV6({ route })) as any; -// return { data, status, totalCount }; -// }; export function useResourcesV6({ route, @@ -75,6 +75,7 @@ export function useResourcesV6({ const [totalCount, setTotalCount] = useState(0); const [sortData, setSortData] = useState([]); const [flattenData, setFlattenData] = useState([]); + const { filters, addFilter, removeFilter } = useColumnFilters(); useEffect(() => { if (data?.data && data?.data?.length > 0) { @@ -117,12 +118,17 @@ export function useResourcesV6({ setSorting, pageIndex, totalCount, - flattenData, + flattenData: applyFilters(flattenData, filters), isError, isLoading, hasNextPage: pageIndex * pageSize + pageSize <= totalCount, fetchNextPage: onFetchNextPage, error, status, + filters: { + filters, + add: addFilter, + remove: removeFilter, + }, }; } diff --git a/packages/manager/core/generator/app/conditional-templates/listing/v2/index.tsx.hbs b/packages/manager/core/generator/app/conditional-templates/listing/v2/index.tsx.hbs index 99200a95747e..a1d403a3ec93 100644 --- a/packages/manager/core/generator/app/conditional-templates/listing/v2/index.tsx.hbs +++ b/packages/manager/core/generator/app/conditional-templates/listing/v2/index.tsx.hbs @@ -1,13 +1,13 @@ import React, { useState, useEffect, } from 'react'; import { useTranslation } from 'react-i18next'; +import { FilterCategories } from '@ovh-ux/manager-core-api'; import { {{#if isPCI }}useParams, {{/if}} useNavigate, useLocation } from 'react-router-dom'; - import { OdsButton } from '@ovhcloud/ods-components/react'; import { ODS_BUTTON_VARIANT } from '@ovhcloud/ods-components'; - import { BaseLayout, Datagrid, + dataType, DataGridTextCell, useResourcesIcebergV2, } from '@ovh-ux/manager-react-components'; @@ -40,6 +40,7 @@ export default function Listing() { setSorting, error, status, + filters, } = useResourcesIcebergV2({ route: `{{#if this.isPCI }}{{this.mainApiPathPci}}{{else}}{{this.mainApiPath}}{{/if}}`, queryKey: ['{{appName}}', `{{#if this.isPCI }}{{this.mainApiPathPci}}{{else}}{{this.mainApiPath}}{{/if}}`], @@ -51,6 +52,14 @@ export default function Listing() { navigate(`${path}${label}`); }; + // Code to remove + const comparatorType = { + number: FilterCategories.Numeric, + data: FilterCategories.Date, + string: FilterCategories.String, + }; + + // Code to remove and declare definition columns in const variable useEffect(() => { if (status === 'success' && data?.pages[0].data.length === 0) { navigate(urls.onboarding); @@ -60,6 +69,12 @@ export default function Listing() { .map((element) => ({ id: element, label: element, + // @ts-ignore + ...(comparatorType[dataType(data?.pages[0].data[0][element])] && { + comparator: + // @ts-ignore + comparatorType[dataType(data?.pages[0].data[0][element])], + }), cell: (props: any) => { const label = props[element] as string; if (typeof label === 'string' || typeof label === 'number') { @@ -107,6 +122,7 @@ export default function Listing() { sorting={sorting} onSortChange={setSorting} manualSorting={false} + filters={filters} /> )} diff --git a/packages/manager/core/generator/app/conditional-templates/listing/v6/index.tsx.hbs b/packages/manager/core/generator/app/conditional-templates/listing/v6/index.tsx.hbs index 82fdeb7f1494..690ff4af53d9 100644 --- a/packages/manager/core/generator/app/conditional-templates/listing/v6/index.tsx.hbs +++ b/packages/manager/core/generator/app/conditional-templates/listing/v6/index.tsx.hbs @@ -1,10 +1,9 @@ import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { FilterCategories } from '@ovh-ux/manager-core-api'; import { {{#if isPCI }} useParams, {{/if}} useNavigate, useLocation } from 'react-router-dom'; - import { OdsButton } from '@ovhcloud/ods-components/react'; import { ODS_BUTTON_VARIANT } from '@ovhcloud/ods-components'; - import { Datagrid, DataGridTextCell, @@ -41,6 +40,7 @@ export default function Listing() { sorting, setSorting, pageIndex, + filters, } = useResourcesIcebergV6({ route: `{{#if this.isPCI }}{{this.mainApiPathPci}}{{else}}{{this.mainApiPath}}{{/if}}`, queryKey: ['{{appName}}', `{{#if this.isPCI }}{{this.mainApiPathPci}}{{else}}{{this.mainApiPath}}{{/if}}`], @@ -52,8 +52,16 @@ export default function Listing() { navigate(`${path}${label}`); }; + // Code to remove + const comparatorType = { + number: FilterCategories.Numeric, + data: FilterCategories.Date, + string: FilterCategories.String, + }; + + // Code to remove and declare definition columns in const variable useEffect(() => { - if (columns && status === 'success' && flattenData?.length > 0) { + if (columns.length === 0 && status === 'success' && flattenData?.length > 0) { const newColumns = Object.keys(flattenData[0]) .filter((element) => element !== 'iam') .map((element) => ({ @@ -61,6 +69,11 @@ export default function Listing() { label: element, // @ts-ignore type: dataType(flattenData[0][element]), + // @ts-ignore + ...(comparatorType[dataType(flattenData[0][element])] && { + // @ts-ignore + comparator: comparatorType[dataType(flattenData[0][element])], + }), cell: (props: any) => { const label = props[element] as string; if (typeof label === 'string' || typeof label === 'number') { @@ -107,6 +120,7 @@ export default function Listing() { onFetchNextPage={fetchNextPage} sorting={sorting} onSortChange={setSorting} + filters={filters} /> )}